超市界面商品价格及会员折扣功能故障技术问询
问题分析与修复方案
核心问题梳理
- 数组传参错误:读取客户姓名时,
scanf("%s",&name)里的name本身就是数组首地址,加&属于多余操作,会导致未定义行为。 - 输入缓冲区残留问题:
- 输入姓名后,换行符会留在输入流里,后续读取会员类型的
scanf会直接读这个换行符,让membershiptype变成换行符,触发switch的默认分支返回-1。 - 原代码里
scanf("%c\n",&membershiptype)的写法错误,\n会强制要求输入流里必须有换行符,反而加重了缓冲区问题。
- 输入姓名后,换行符会留在输入流里,后续读取会员类型的
- 折扣判断逻辑不匹配:
getDiscountPercent在会员类型非法时返回-1,但主函数里判断if (discount==1)才跳转重新输入,条件对不上,导致非法类型无法触发重新输入。 - 未定义行为调用:
fflush(stdin)是C标准未定义的操作,不同编译器表现不一样,不能用来清空输入缓冲区。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> //#jeremiahtask4 int getDiscountPercent(char); int main() // 标准C要求main必须返回int类型 { float itemprice, discountedprice, totalpurchase = 0.00, totalafterdis = 0.00; int discount, itemnum = 0; char membershiptype, additem = 'Y', name[20]; printf(" Suria Supermarket\n"); printf("\nEnter customer name:"); scanf("%s", name); // 去掉多余的&,数组名直接作为首地址传递 printf("\nEnter membership type:"); reenter: // 前面加空格,自动跳过输入流里的空白字符(换行、空格等) scanf(" %c", &membershiptype); discount = getDiscountPercent(membershiptype); if (discount == -1) // 匹配函数返回的非法值,触发重新输入 goto reenter; do { itemnum++; printf("\nItem %d", itemnum); printf("\nEnter item price:"); scanf("%f", &itemprice); discountedprice = itemprice * (100 - discount) / 100.00; printf("\n\nDiscount(%%):%d", discount); printf("\nDiscounted price:%.2f\n", discountedprice); printf("\n\nAdd items (Y/N):"); // 用循环读取到换行符,安全清空缓冲区,替代fflush(stdin) while (getchar() != '\n'); scanf("%c", &additem); totalpurchase += itemprice; totalafterdis += discountedprice; } while (additem == 'Y' || additem == 'y'); printf("\n *** Purchase Details ***"); printf("\nCustomer Name:%s", name); printf("\nNumber of items is:%d", itemnum); printf("\nTotal purchase:%.2f", totalpurchase); printf("\nAmount to pay:%.2f\n", totalafterdis); return 0; // 标准main函数需要返回值 } int getDiscountPercent(char membershiptype) { int discount; // 删掉函数内不必要的冗余变量声明 switch(membershiptype) { case 'p': case 'P': discount = 30; break; case 'g': case 'G': discount = 20; break; case 's': case 'S': discount = 10; break; case 'x': case 'X': discount = 0; break; default: discount = -1; // 去掉多余的空语句 } return discount; }
关键修复说明
- 数组传参修正:
scanf("%s", name)正确传递数组首地址,避免地址错误。 - 缓冲区处理优化:
- 读取会员类型时,
scanf(" %c", &membershiptype)里的空格会自动跳过输入流中的空白字符,解决换行残留问题。 - 用
while (getchar() != '\n')替代fflush(stdin),安全清空输入缓冲区,符合C标准规范。
- 读取会员类型时,
- 逻辑匹配修正:把
if (discount==1)改成if (discount==-1),和getDiscountPercent返回的非法值匹配,确保非法会员类型会触发重新输入。 - 代码规范优化:补充
main函数的返回值声明和返回语句,移除函数内不必要的变量声明,提升代码可读性。
内容的提问来源于stack exchange,提问作者Joel Matts
相关产品推荐
相关产品推荐

