水果商店C++收银程序收据显示问题及代码优化求助
问题修复与代码简化方案(针对Only Fresh Fruit Shop收银程序)
现有代码的核心问题
- 收据无内容:
cart数组从未被写入数据,index变量始终为0,导致收据循环完全不执行。 - 金额计算错误:
current = prices[key] + weight错误地将单价与重量相加,正确逻辑应为单价 × 重量。 - 无输入验证:用户输入的水果编码可能超出0-4范围,会触发数组越界访问,引发未定义行为。
- 代码冗余:水果名称和价格在
getItemName函数与菜单输出中重复定义,后续修改需同步多处,维护成本高。 - 重量精度受限:
weight被定义为int类型,无法处理小数重量(如1.5kg)。
代码简化与改进方法
- 用结构体封装水果数据:将名称、单价绑定在一起,避免重复硬编码,方便后续扩展新水果。
- 替换固定数组为
std::vector:存储购物车项,无需预先设定最大容量,更灵活安全。 - 简化名称获取逻辑:通过结构体数组直接索引,替代冗长的if-else链。
- 添加输入验证:检查用户输入的编码是否合法,避免越界。
- 提取重复逻辑为函数:比如菜单打印、收据项格式化,让代码结构更清晰。
- 优化金额显示:使用格式化输出保证金额显示两位小数,符合收银场景需求。
改进后的完整代码
#include <iostream> #include <string> #include <vector> #include <iomanip> #include <sstream> using namespace std; // 封装水果名称与单价的结构体 struct Fruit { string name; double pricePerKg; }; // 预定义水果列表,修改/添加水果只需调整此处 const vector<Fruit> fruits = { {"Sunkist Orange", 2.00}, {"Strawberry", 22.00}, {"Papaya", 5.00}, {"Star Fruit", 6.00}, {"Kiwi", 10.00} }; // 打印商品菜单 void printMenu() { cout << "Welcome to Only Fresh Fruit Shop\n\nToday's fresh fruit <Price per Kg>\n"; for (size_t i = 0; i < fruits.size(); ++i) { cout << i << "-" << fruits[i].name << " RM" << fruits[i].pricePerKg << "\n"; } } int main() { double total = 0.0; vector<string> cart; // 存储收据明细项 int key = 0; double weight = 0.0; // 改为double支持小数重量 printMenu(); while (true) { cout << "\nEnter fruit code <-1 to stop>: "; cin >> key; if (key == -1) { break; } // 验证输入编码是否合法 if (key < 0 || key >= static_cast<int>(fruits.size())) { cout << "Invalid code! Please enter a number between 0 and " << fruits.size() - 1 << endl; continue; } const Fruit& selected = fruits[key]; cout << "Selected: " << selected.name << endl; cout << "Enter weight <kg>: "; cin >> weight; // 计算当前商品总价 double itemTotal = selected.pricePerKg * weight; total += itemTotal; // 格式化收据项并添加到购物车 ostringstream oss; oss << fixed << setprecision(2); oss << selected.name << " - " << weight << "kg @ RM" << selected.pricePerKg << " = RM" << itemTotal; cart.push_back(oss.str()); } // 打印完整收据 cout << "\n-------------------------------------------------------\nReceipt\n"; for (const string& item : cart) { cout << item << "\n"; } cout << "-------------------------------------------------------\n"; cout << fixed << setprecision(2) << "TOTAL = RM" << total << endl; return 0; }
关键改进说明
- 结构体封装:水果数据集中管理,新增/修改水果只需调整
fruits列表,无需修改多处代码。 - 输入合法性检查:拦截非法编码输入,避免数组越界风险。
- 购物车填充逻辑:每次选择商品后,格式化生成收据明细并存入
cart,确保收据能正常显示所有购买项。 - 精度优化:重量改为
double类型,金额输出固定两位小数,符合实际收银场景。 - 灵活存储:用
std::vector替代固定大小数组,无需担心购物车容量不足。
内容的提问来源于stack exchange,提问作者KatanaXI
相关产品推荐
相关产品推荐

