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

如何重构C语言do-while循环以避免非法输入引发的无限循环

解决非法输入导致的程序无限循环问题

原代码在输入1、2、3、4之外的非法内容时会陷入无限循环,根本原因是**scanf("%d", &choice)读取失败时,非法输入会滞留在输入缓冲区中**,后续循环里scanf会反复读取这些无效内容,永远触发default分支,导致死循环。你尝试用count变量控制循环次数的方案只是临时规避,不能从根源解决问题。

原代码

do {
    printf("\n\t***CHOOSE HOW TO SORT***\n\n\tBy firstname: 1\n\tBy lastname: 2\n\tBy age: 3\n\tExit Program: 4\n\n");
    scanf("%d", &choice);
    switch (choice) {
        case 1:
        printf("\t***SORTING BY FIRSTNAME...***\n\n");
        qsort(P, n, sizeof *P, Person_cmp_firstname);
        printf("\t***DONE***\n\n");
        for (i = 0; i < n; i++) {
            printf("Firstname: %s\t| Lastname: %s\t| Age: %d\n", P[i]->firstname, P[i]->lastname, P[i]->age);
        }
        break;
        
        case 2:
        printf("\t***SORTING BY LASTNAME...***\n\n");
        qsort(P, n, sizeof *P, Person_cmp_lastname);
        printf("\t***DONE***\n\n");
        for (i = 0; i < n; i++) {
            printf("Firstname: %s\t| Lastname: %s\t| Age: %d\n", P[i]->firstname, P[i]->lastname, P[i]->age);
        }
        break;
        
        case 3:
        printf("\t***SORTING BY AGE...***\n\n");
        qsort(P, n, sizeof *P, Person_cmp_age);
        printf("\t***DONE***\n\n");
        for (i = 0; i < n; i++) {
            printf("Firstname: %s\t| Lastname: %s\t| Age: %d\n",P[i]->firstname, P[i]->lastname, P[i]->age);
        }
        break;
        
        case 4:
        printf("\t***EXITING PROGRAM***\n\n");
        for (i = 0; i < n; i++) {
            free(P[i]);
        }
        exit(0);
        
        default:
        printf("\t***INVALID OPTION***\n\n");
        break;
    }
} while (1);

你的尝试代码片段

...
default:
            printf("\t***INVALID OPTION***\n\n");
            count = count + 2;
            break;
        }
    }while(count < 2);

正确重构方案

核心要做两件事:

  1. 检查scanf的返回值:scanf("%d", &choice)成功读取整数时返回1,读取失败(输入非数字)时返回0,遇到EOF返回-1。
  2. 清空输入缓冲区:读取失败时,把缓冲区里的非法内容全部清空,避免下次循环重复读取。

修改后的完整代码:

do {
    printf("\n\t***CHOOSE HOW TO SORT***\n\n\tBy firstname: 1\n\tBy lastname: 2\n\tBy age: 3\n\tExit Program: 4\n\n");
    // 检查scanf返回值,判断是否成功读取整数
    int scan_result = scanf("%d", &choice);
    
    // 处理读取失败的情况:清空输入缓冲区
    if (scan_result != 1) {
        printf("\t***INVALID OPTION***\n\n");
        // 清空缓冲区直到换行符,避免残留内容影响下次读取
        while ((getchar()) != '\n');
        continue; // 跳过后续switch,直接进入下一轮循环
    }

    switch (choice) {
        case 1:
        printf("\t***SORTING BY FIRSTNAME...***\n\n");
        qsort(P, n, sizeof *P, Person_cmp_firstname);
        printf("\t***DONE***\n\n");
        for (i = 0; i < n; i++) {
            printf("Firstname: %s\t| Lastname: %s\t| Age: %d\n", P[i]->firstname, P[i]->lastname, P[i]->age);
        }
        break;
        
        case 2:
        printf("\t***SORTING BY LASTNAME...***\n\n");
        qsort(P, n, sizeof *P, Person_cmp_lastname);
        printf("\t***DONE***\n\n");
        for (i = 0; i < n; i++) {
            printf("Firstname: %s\t| Lastname: %s\t| Age: %d\n", P[i]->firstname, P[i]->lastname, P[i]->age);
        }
        break;
        
        case 3:
        printf("\t***SORTING BY AGE...***\n\n");
        qsort(P, n, sizeof *P, Person_cmp_age);
        printf("\t***DONE***\n\n");
        for (i = 0; i < n; i++) {
            printf("Firstname: %s\t| Lastname: %s\t| Age: %d\n",P[i]->firstname, P[i]->lastname, P[i]->age);
        }
        break;
        
        case 4:
        printf("\t***EXITING PROGRAM***\n\n");
        for (i = 0; i < n; i++) {
            free(P[i]);
        }
        exit(0);
        
        default:
        printf("\t***INVALID OPTION***\n\n");
        break;
    }
} while (1);

关键说明

  • 通过scan_result = scanf("%d", &choice)获取读取状态,判断是否成功读取整数。
  • 读取失败时,用while ((getchar()) != '\n');清空输入缓冲区里的所有字符直到换行符,确保下一轮循环的scanf能正常读取新的输入。
  • 用continue直接进入下一轮循环,避免执行后续的switch逻辑。

内容的提问来源于stack exchange,提问作者jian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:33:38