如何修改收银程序代码在receipt.dat中显示所有已购商品清单?
修改C语言收银程序以生成包含所有商品明细的收据
原代码存在的核心问题
- 未初始化文件指针就写入:程序前半段调用
fprintf(fp)时,fp还未通过fopen初始化,属于未定义行为,无法正常写入内容 - 未存储所有商品信息:仅用单个变量保存当前商品的价格和数量,未记录全部商品明细,导致收据无法列出所有已购商品
- 收据内容错误:仅输出最后一件商品的数量,且
Grand total错误使用了$符号(应为RM)
修改后的完整代码
#include<stdio.h> #include<stdlib.h> #define MAX_ITEMS 50 // 可按需调整最大商品数量 int main() { float prices[MAX_ITEMS]; int quantities[MAX_ITEMS]; float amount = 0.0, discount = 0.0, amountToBePaid, cash, change; int counter = 0; char decision; FILE *fp; printf("============\n"); printf("Happy Market\n"); printf("============\n\n"); do { counter++; printf("Input item #%d price: RM ", counter); scanf("%f", &prices[counter-1]); printf("Quantity: "); scanf("%d", &quantities[counter-1]); amount += prices[counter-1] * quantities[counter-1]; printf("Current total is RM %.2f\n", amount); printf("\nAdd another item? (Y/N) :"); scanf(" %c", &decision); } while (decision == 'Y' || decision == 'y'); // 计算折扣 if(amount <= 100) { discount = (amount * 10) / 100; printf("\nTotal discount: RM%.2f", discount); printf("\nDiscount eligible is 10 percent"); } else if(amount > 100 && amount < 200) { discount = (amount * 15) / 100; printf("\nTotal discount: RM%.2f", discount); printf("\nDiscount eligible is 15 percent"); } else if(amount >= 200 && amount < 300) { discount = (amount * 20) / 100; printf("\nTotal discount: RM%.2f", discount); printf("\nDiscount eligible is 20 percent"); } else if(amount >= 300) { discount = (amount * 25) / 100; printf("\nTotal discount: RM%.2f", discount); printf("\nDiscount eligible is 25 percent"); } amountToBePaid = amount - discount; printf("\n*******************************"); printf("\nItem(s) sub total: RM %.2f", amount); printf("\n*******************************"); printf("\n\nGrand total: RM%0.2f", amountToBePaid); printf("\nAmount received: RM "); scanf("%f", &cash); change = cash - amountToBePaid; printf("Change: RM %.2f", change); printf("\n\n*******************************"); printf("\nThank you, please come again!"); // 打开文件并写入收据 fp = fopen("receipt.dat", "w"); if(fp == NULL) { printf("\nError opening file!"); return 1; } fprintf(fp,"*******************************\n"); fprintf(fp,"HAPPY MARKET\n"); fprintf(fp,"*******************************\n"); fprintf(fp,"%-10s %-15s %-10s %-10s\n", "Item No.", "Price (RM)", "Quantity", "Subtotal"); fprintf(fp,"-----------------------------------------\n"); // 遍历写入所有商品明细 for(int i = 0; i < counter; i++) { float subtotal = prices[i] * quantities[i]; fprintf(fp,"%-10d %-15.2f %-10d %-10.2f\n", i+1, prices[i], quantities[i], subtotal); } fprintf(fp,"-----------------------------------------\n"); fprintf(fp,"Sub total:\t\t RM%.2f\n", amount); fprintf(fp,"Discount:\t\t RM%.2f\n", discount); fprintf(fp,"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); fprintf(fp,"Grand total:\t\t RM%.2f\n", amountToBePaid); fprintf(fp,"Amount received:\t RM%.2f\n", cash); fprintf(fp,"Change:\t\t\t RM%.2f\n", change); fprintf(fp,"*******************************\n"); fprintf(fp,"Thank you, please come again!\n"); fclose(fp); return 0; }
关键修改说明
- 添加商品存储结构:用两个数组
prices和quantities分别保存每件商品的价格和数量,确保所有商品信息被完整记录 - 修正文件操作逻辑:仅在需要写入收据时打开文件,同时增加文件打开失败的判断,避免程序异常
- 生成商品明细:通过循环遍历数组,将每件商品的编号、价格、数量、小计写入收据,符合预期格式
- 修复符号错误:把
Grand total中的$改为RM,保持货币单位统一 - 优化输入循环:改用
do-while循环,避免重复编写初始商品输入代码,逻辑更简洁
内容的提问来源于stack exchange,提问作者L4Lebbit
相关产品推荐
相关产品推荐

