结构体数组流式传入的餐厅点餐系统printCheck函数未执行求助
Hey there, let's walk through the problems in your code that are causing it to terminate before printCheck runs, plus other bugs that'll mess up your order flow:
Key Issues & Fixes
1. printCheck Isn't Being Called Properly
In your main function, printCheck; doesn't actually invoke the function—it just references its address. Worse, you aren't passing the total order amount that showMenu calculates.
To fix this, we need to modify showMenu to return the total (or use a reference parameter) so we can pass it to printCheck.
2. Uninitialized Variables Cause Undefined Behavior
In showMenu, both selection and total are declared but not initialized:
selectionstarts with a garbage value, sowhile (selection != sentinel)might exit immediately or loop infinitely.totalstarts with a random value, so your order total will be wrong.
Initialize them like this:
int selection = 0; double total = 0.0;
3. Hardcoded Prices Break the Struct's Purpose
You're using fixed values like 2.45 for Bacon instead of pulling the price from your menuList struct. This defeats the point of reading from menuitems.txt—if you update the file, your code won't reflect the change. Use menuList[selection - 1].menuPrice instead (since selections are 1-based, but the array is 0-based).
4. No Error Checking for File Reads
Your getData function doesn't check if menuitems.txt opened successfully. If the file is missing or inaccessible, your program will read invalid data. Add a check:
in_stream.open("menuitems.txt"); if (!in_stream) { cerr << "Error opening menuitems.txt!" << endl; exit(1); // Exit if file can't be opened }
5. Loop Logic Doesn't Handle Invalid Inputs
Right now, if a user enters something other than 1-3 or 9, your code does nothing. Add an else clause to prompt them to enter a valid option.
Corrected Full Code
//Module 9 Project #include <iostream> #include <string> #include <iomanip> #include <fstream> #include <cstdlib> // For exit() using namespace std; struct menuItemType { string menuItem; double menuPrice; }; menuItemType menuList[3]; void getData(menuItemType menuList[3]); double showMenu(menuItemType menuList[3]); // Modified to return total void printCheck(double total); int main(){ getData(menuList); double orderTotal = showMenu(menuList); // Capture the total from showMenu printCheck(orderTotal); // Call printCheck with the total return 0; } void getData(menuItemType menuList[3]) //该函数从文本文件读取菜品信息存入结构体数组 { //声明变量 ifstream in_stream; int i; //打开文本文件并检查是否成功 in_stream.open("menuitems.txt"); if (!in_stream) { cerr << "Failed to open menuitems.txt. Exiting..." << endl; exit(EXIT_FAILURE); } //循环读取文本文件内容存入结构体数组 for (i = 0; i < 3 ; i++){ in_stream >> menuList[i].menuItem >> menuList[i].menuPrice; } in_stream.close(); // Don't forget to close the file! } double showMenu(menuItemType menuList[3])//向用户展示菜单并说明点餐方式 { int selection = 0; // Initialize selection double total = 0.0; // Initialize total to 0 int sentinel = 9; //欢迎信息及点餐说明 cout << "Welcome To The Restaurant" << endl; cout << "Please select the items you would like: " << endl; cout << "Press 9 to complete your order." << endl; //将结构体数组中的菜品信息展示到屏幕,编号对应选择项 cout << "1. " << menuList[0].menuItem << " $" << menuList[0].menuPrice << endl; cout << "2. " << menuList[1].menuItem << " $" << menuList[1].menuPrice << endl; cout << "3. " << menuList[2].menuItem << " $" << menuList[2].menuPrice << endl; //循环接收用户点餐并计算总价 while (selection != sentinel){ cin >> selection; if (selection == 1){ total += menuList[0].menuPrice; // Use struct price instead of hardcode cout << "You've selected " << menuList[0].menuItem << endl; } else if (selection == 2){ total += menuList[1].menuPrice; cout << "You've selected " << menuList[1].menuItem << endl; } else if (selection == 3) { total += menuList[2].menuPrice; cout << "You've selected " << menuList[2].menuItem << endl; } else if (selection != sentinel) { // Handle invalid inputs cout << "Invalid selection! Please choose 1-3 or 9 to finish." << endl; } } return total; // Return the calculated total to main } void printCheck(double total) { double after_tax; const double tax = 0.05; cout << "\n--- Your Bill ---" << endl; cout << fixed << setprecision(2); // Ensure 2 decimal places for currency cout << "Subtotal: $" << total << endl; after_tax = total + (total * tax); cout << "Total Check After Tax: $" << after_tax << endl; }
Notes on the Fixes
showMenunow returns the total order amount, which we capture inmainand pass toprintCheck.- Added
fixedtoprintCheckso currency values always show two decimal places (e.g., $2.45 instead of $2.4 or $2). - Added file closing in
getDatato avoid resource leaks. - Added clear prompts for invalid inputs to improve user experience.
内容的提问来源于stack exchange,提问作者Kcrizzle87

