C++文件写入错误:选中单道菜却写入全部菜品求助
Hey there! Let's get that incorrect file write sorted out right away. The core problem in your code is that you're writing every menu item to the file, regardless of whether it's the one the user selected—here's why and how to fix it:
What's Going Wrong
In your Search function's loop, the code that writes to transactions.txt is placed outside the if statement that checks for the user's selected dish. That means every iteration of the loop (for every menu item) executes the write, even when the item doesn't match the user's input.
Take a look at your original problematic loop:
for(int i = 0; i < r.size(); i++) { if(r[i].itemNo.find(n) != string::npos) cout << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price; // This runs for EVERY menu item, not just the matched one std::ofstream ofs; ofs.open ("transactions.txt", std::ofstream::out | std::ofstream::app); ofs << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price << "\n"; }
The Corrected Code
We need to move the file write logic inside the if block, and also optimize file handling by opening the file once instead of every loop iteration:
void Search(vector<MenuList>& r) {// Search records for itemNo string n; int a; char cont; cout << "Order\n_______\n"; do { cout << "Enter quantity: "; cin >> a; cout << "Enter dish: "; cin >> n; // Open the transaction file ONCE before processing std::ofstream ofs("transactions.txt", std::ofstream::out | std::ofstream::app); if (!ofs.is_open()) { cout << "Error: Could not open transactions file!\n"; cin >> cont; // Still let user choose to continue continue; } bool dishFound = false; for(int i = 0; i < r.size(); i++) { if(r[i].itemNo.find(n) != string::npos) { // Only execute these lines when the dish matches cout << r[i].category << " - " << r[i].descript << ' ' << a*r[i].price << "\n"; ofs << r[i].category << " - " << r[i].descript << ' ' << a*r[i].price << "\n"; dishFound = true; // Break the loop since item numbers are unique (no need to check others) break; } } if (!dishFound) { cout << "Error: Dish number " << n << " not found!\n"; } ofs.close(); // Close the file after processing this order entry cout << "\n\nContinue to add to order?(y)"; cin >> cont; }while(cont == 'y'); }
Key Improvements
- Write only matched items: The file write is now inside the
ifblock, so only the user's selected dish gets written totransactions.txt. - Optimize file I/O: Opening the file once per order entry (instead of every loop iteration) is more efficient and avoids potential file access issues.
- Error handling: Added checks for file opening failures and missing dish numbers to make the program more robust.
- Early loop exit: Used
breakto stop searching once the matching dish is found (since your menu uses unique item numbers).
Bonus: Clean Up Menu Loading
One small side issue: when loading your menu file, the operator>> leaves a newline in the input stream, which can cause problems with subsequent reads. To fix that, add a call to ignore() after reading the price:
std::istream& operator>>(std::istream& infile, MenuList& menu) { getline(infile, menu.itemNo, ':'); getline(infile, menu.category, ':'); getline(infile, menu.descript, ':'); infile >> menu.price; infile.ignore(); // Skip the newline after the price return infile; }
This ensures your menu loads correctly without extra empty records.
内容的提问来源于stack exchange,提问作者jack.dale

