C语言如何防止非整数输入?仅允许输入1或2的校验实现问题
问题解决方法
问题根源
- 未处理
scanf的返回值:当输入非整数内容时,scanf("%d")匹配失败返回0,输入的非法内容会滞留在输入缓冲区,后续scanf会反复读取该残留内容,导致程序逻辑错乱。 - 递归重试逻辑存在缺陷:多次输入错误时会叠加函数调用栈,即使后续输入正确,上层递归的
userSel还是之前的错误值,最终输出结果不符合预期。 - 未清理输入缓冲区残留内容:输入非法内容后没有清空缓冲区的剩余数据,会干扰下一次输入读取。
修正后的代码
#include <stdio.h> int getUserInput(){ // 将变量改为局部变量避免全局变量的不可控问题,需要外部使用可改为指针参数或返回结构体 int userSel, userNo; int scanRet; while(1) { printf("1: You have chosen 1.\n"); printf("2: You have chosen 2.\n\n"); printf("Enter an option: "); // 读取输入同时获取scanf返回值,返回值代表成功匹配的变量个数 scanRet = scanf("%d", &userSel); // 先判断是否成功读取整数,再判断数值是否符合要求 if(scanRet!= 1 || (userSel!= 1 && userSel!= 2)) { printf("You have entered an invalid input. Please try again.\n"); // 清空输入缓冲区剩余的所有内容,直到读到换行或文件结束 while(getchar()!= '\n' && getchar()!= EOF); continue; } // 输入合法则跳出循环 break; } printf("Enter a number: "); // 第二个输入如果也需要做非法校验,可以复用上面的判断逻辑 scanf("%d", &userNo); printf("userSelection: %d\n", userSel); printf("userNumber: %d\n", userNo); return 0; }
改动说明
- 把递归重试改成了
while(1)循环的重试逻辑,避免函数栈溢出问题,同时保证合法读取到的值直接在当前函数层生效。 - 新增
scanf返回值校验:返回值不为1时直接判定为输入非法,覆盖非整数输入的场景。 - 新增输入缓冲区清理逻辑:每次输入非法后清空当前行残留内容,避免干扰下一次输入读取。
内容的提问来源于stack exchange,提问作者thompsonrapier
相关产品推荐
相关产品推荐

