You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言商店程序输入非数字字符触发无限循环,如何修复?

修复C语言购物程序输入非数字时的无限循环问题

你的程序陷入无限循环的核心原因是**scanf读取非数字输入时匹配失败,无效字符会滞留在输入缓冲区中**。每次循环时scanf("%d", &choice)都会反复读取这个无效字符,导致匹配持续失败,choice的值无法被正确更新,循环条件choice != 0永远成立,最终陷入死循环。


修复步骤

  1. 检查scanf的返回值:scanf会返回成功读取的变量数量,读取整数时如果输入非数字,返回值为0。通过判断这个返回值可直接识别无效输入。
  2. 清空输入缓冲区:当scanf匹配失败时,用循环读取缓冲区中所有剩余字符直到换行符,避免无效字符干扰后续输入。
  3. 跳过无效输入后的冗余逻辑:输入无效时,直接回到选择输入步骤,跳过商品数量输入等后续操作。

修改后的完整代码

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:35:24