C语言测验成绩录入程序BUG排查及修复咨询
问题根因分析
两处异常均由代码的基础逻辑错误导致,具体如下:
- 异常1(自动填充数组)的原因:运算符优先级使用错误,
&&优先级高于赋值运算符=,原代码while (ib=scanf("%d",&grade) && last<N-1)实际执行逻辑是ib = (scanf("%d",&grade) && last<N-1)。当用户触发输入终止(如按Ctrl+D/Ctrl+Z)时,scanf返回EOF(值为-1,逻辑上为真),只要数组还没填满,整个与运算结果为真,ib被赋值为1进入循环,且scanf返回EOF时不会修改grade变量,就会一直用上一次输入的合法成绩填充数组直到存满10个。 - 异常2(输入非数字直接退出)的原因:同样是优先级错误,当输入非数字时
scanf返回0,0 && 任意值结果为0,ib被赋值为0,整个while循环的判断条件结果为假,直接跳出循环停止运行,不会进入错误处理分支。
修复方案
- 修正while循环的运算符优先级,给
scanf赋值逻辑加括号,确保先拿到scanf的真实返回值再做后续判断 - 调整循环逻辑:仅当用户主动输入终止信号(EOF)或数组存满10个成绩时才退出循环,输入非法内容时停留在当前输入步骤提示重试
- 补全所有场景的输入提示,新增合法输入后的下一步提示,修正范围错误提示的换行避免显示混乱
- 所有输入异常场景都正确清空输入缓冲区,避免残留内容干扰后续输入
修复后的完整代码如下:
#include <stdio.h> #define N 10 /* 班级学生人数 */ int main() { int quiz[N], /* 存储测验成绩的数组 */ grade, /* 临时存储单次读入的成绩 */ last, /* 数组最后一个已使用元素的下标 */ ib; /* scanf的返回值 */ char c; last = -1; printf("请输入测验成绩(最多输入%d个,输入Ctrl+Z/Ctrl+D结束输入):\n", N); // 修正优先级:先赋值ib,再判断是否未终止且数组未满 while ( (ib = scanf("%d", &grade)) != EOF && last < N-1 ) { if(ib == 0 ){ // 非数字输入 printf("输入无效,请输入合法的数字成绩:"); // 清空输入缓冲区 while((c=getchar())!='\n' && c!=EOF); } else { if(grade >= 0 && grade <= 10) { last++; quiz[last] = grade; // 已存满则直接跳出 if(last == N-1){ printf("已达到最大输入数量,输入结束\n"); break; } printf("请输入下一个成绩:"); } else{ printf("成绩范围需在0到10之间,请重新输入:"); } // 清空数字输入后残留的换行符 while((c=getchar())!='\n' && c!=EOF); } } // 可选:输出最终存入的成绩验证结果 printf("\n已存入的有效成绩共%d个:\n", last+1); for(int i=0; i<=last; i++){ printf("%d ", quiz[i]); } printf("\n"); return 0; }
内容的提问来源于stack exchange,提问作者Sofia Lazrak
相关产品推荐
相关产品推荐

