C语言商店程序输入非数字字符触发无限循环,如何修复?
修复C语言购物程序输入非数字时的无限循环问题
你的程序陷入无限循环的核心原因是**scanf读取非数字输入时匹配失败,无效字符会滞留在输入缓冲区中**。每次循环时scanf("%d", &choice)都会反复读取这个无效字符,导致匹配持续失败,choice的值无法被正确更新,循环条件choice != 0永远成立,最终陷入死循环。
修复步骤
- 检查
scanf的返回值:scanf会返回成功读取的变量数量,读取整数时如果输入非数字,返回值为0。通过判断这个返回值可直接识别无效输入。 - 清空输入缓冲区:当
scanf匹配失败时,用循环读取缓冲区中所有剩余字符直到换行符,避免无效字符干扰后续输入。 - 跳过无效输入后的冗余逻辑:输入无效时,直接回到选择输入步骤,跳过商品数量输入等后续操作。
修改后的完整代码
#include <stdio.h> int main(void) { int choice, quantity, total = 0, price = 0; char end; do { total = 0; // 每次重新购物时重置总价,原代码遗漏该逻辑 printf("\nWelcome to our store!\n\n"); printf("Please select a product from the following list:\n"); printf("1. Oishi Prawn Crackers - 7 PHP\n"); printf("2. Piattos - 16 PHP\n"); printf("3. Coca-Cola - 40 PHP\n"); printf("4. Sting Energy Drink - 25 PHP\n"); printf("5. Gatorade - 43 PHP\n"); printf("6. Nature Spring 500mL - 10 PHP\n"); printf("7. KitKat - 30 PHP\n"); printf("8. Snickers - 44 PHP\n"); printf("9. Pringles - 40 PHP\n"); // 修正原代码商品名重复/错误问题 printf("10. M&M's - 80 PHP\n"); printf("Enter 0 to finish.\n"); printf("\nProduct Quantity Price\n"); printf("----------------------------------------\n"); do { printf("Enter your choice: "); // 检查scanf返回值,判断是否成功读取整数 int scan_result = scanf("%d", &choice); if (scan_result == 0) { printf("Invalid input! Please enter a number.\n"); // 清空输入缓冲区的无效字符 while ((getchar()) != '\n'); continue; // 回到输入选择步骤 } if (choice == 0) { break; } // 检查选择是否在有效范围内 if (choice < 1 || choice > 10) { printf("Invalid choice.\n"); continue; } printf("Enter the quantity: "); // 对数量输入做同样的有效性校验 while (scanf("%d", &quantity) == 0) { printf("Invalid quantity! Please enter a number.\n"); while ((getchar()) != '\n'); printf("Enter the quantity: "); } switch (choice) { case 1: printf("Oishi Prawn Crackers %d %d\n", quantity, price = 7 * quantity); total += 7 * quantity; break; case 2: printf("Piattos %d %d\n", quantity, price = 16 * quantity); total += 16 * quantity; // 修正原代码总价计算错误(原用15) break; case 3: printf("Coca-Cola %d %d\n", quantity, price = 40 * quantity); total += 40 * quantity; break; case 4: printf("Sting Energy Drink %d %d\n", quantity, price = 25 * quantity); total += 25 * quantity; break; case 5: printf("Gatorade 500mL %d %d\n", quantity, price = 43 * quantity); total += 43 * quantity; break; case 6: printf("Nature Spring 500mL %d %d\n", quantity, price = 10 * quantity); total += 10 * quantity; break; case 7: printf("KitKat %d %d\n", quantity, price = 30 * quantity); total += 30 * quantity; break; case 8: printf("Snickers %d %d\n", quantity, price = 44 * quantity); total += 44 * quantity; break; case 9: printf("Pringles %d %d\n", quantity, price = 40 * quantity); total += 40 * quantity; break; case 10: printf("M&M's %d %d\n", quantity, price = 80 * quantity); total += 80 * quantity; break; } } while (choice != 0); printf("----------------------------------------\n"); printf("Total cost: %d PHP\n", total); printf("Thank you for shopping with us!\n"); printf("\nWant to Buy Again?\n"); printf("Y if Yes\n"); printf("Type any key if No\n"); scanf(" %c", &end); switch (end) { case 'Y': case 'y': // 支持小写y输入 printf("\nOK!\n"); break; default: printf("\nBYE!\n"); break; } } while (end == 'Y' || end == 'y'); return 0; }
额外优化点
- 每次重新购物时重置
total为0,避免累计上一次的总价 - 修正原代码中case2的总价计算错误(原用15*quantity,实际应为16)
- 修正商品列表与switch分支中商品名不匹配的问题(原case9与case1商品名重复)
- 支持小写
y作为继续购物的输入 - 对商品数量输入也做了无效处理,避免出现同样的无限循环问题
内容的提问来源于stack exchange,提问作者DumpedBrain
相关产品推荐
相关产品推荐

