C语言scanf对非纯整数输入返回非0值的解决方法咨询
问题根因
scanf("%d",&choice)的匹配规则是仅读取输入前缀符合整数格式的字符,只要前缀存在至少1位合法数字,就会返回1(表示成功匹配1个参数),后续的非数字字符会留在输入缓冲区,不会触发匹配失败,这就是你输入1k时仍会判定为输入成功的原因。
解决方案
方案1:基于原有scanf逻辑改造
通过追加匹配末尾字符的方式校验输入是否存在多余内容,修改后的代码如下:
int getChoice(){ int choice = 0; int matchRes; char trailing; while (1) { matchRes = scanf("%d%c", &choice, &trailing); // 满足3个条件才判定输入合法:成功匹配2个项、末尾字符为换行、数值符合范围要求 if (matchRes == 2 && trailing == '\n' && legalSwitch(choice)) { break; } clearBuffer(); printf("\nWrong choice, please choose an integer between 1 to 3: "); } return choice; }
如果你允许输入整数后加空格再换行,可将判断条件改为
trailing == '\n' || isspace(trailing)即可。
方案2:先读整行再校验(更稳妥)
完全规避scanf的匹配遗留问题,先读取整行输入再校验是否为纯数字:
#include <stdlib.h> #include <ctype.h> int getChoice(){ int choice = 0; char buf[1024]; char *endPtr; while (1) { if (!fgets(buf, sizeof(buf), stdin)) continue; choice = strtol(buf, &endPtr, 10); // 校验规则:不是空输入、转换到了行尾、数值符合范围要求 if (endPtr != buf && (*endPtr == '\0' || *endPtr == '\n') && legalSwitch(choice)) { break; } printf("\nWrong choice, please choose an integer between 1 to 3: "); } return choice; }
这个方案可以精准判断输入是否仅由数字组成,不会出现前缀匹配误判的问题。
内容的提问来源于stack exchange,提问作者Flyleaf
相关产品推荐
相关产品推荐

