我正在尝试制作一个用户将值输入到数组的程序。实际需要的是程序应针对char字符进行验证。因此,如果用户输入了诸如'n'之类的随机字符,程序应告诉他“您引入了一个字符,请输入一个整数:”。
在不使用char变量的情况下如何做到这一点?
for (i = 1; i <= size; i++) {
printf("Introduce the value #%d of the list: ", i);
scanf("%d", &list[i]);
if () { // I'm blocked right in this line of code.
printf("What you tried to introduce is a char, please input an integer: ");
scanf("%d", &list[i]);
}
谢谢。
答案 0 :(得分:2)
如@MFisherKDX所述,检查scanf
的返回值。来自scanf man page:
这些函数返回成功匹配的输入项目数 和分配的数量,可以少于提供的数量,甚至为零 早期匹配失败的事件。
如果在任一输入之前到达输入结束,则返回EOF值 首次成功转换或匹配失败。 EOF是 如果发生读取错误,也会返回该错误 流的指示符(请参阅ferror(3))已设置,并且errno已设置 指出错误。
因此,在scanf
变量中捕获int
的返回值,然后将该变量与1
进行比较(在您的情况下,因为您仅尝试读取1个项目)应该说明scanf
成功读取一个整数值。
但是,使用scanf
时需要注意一个nasty pitfall。如果确实在提示符下键入n
,则scanf
将失败并返回0
,但 not 也将消耗您输入的内容。这意味着下次您调用scanf
时,它将读取相同的输入(您键入的n
字符),并再次失败。无论您叫多少次scanf
,它都会继续这样做。令我感到惊讶的是,不仅有这种潜在的陷阱,而且several other pitfalls也使计算机科学教育者继续向学生教授scanf
。我希望每小时都能得到一个镍,某个地方的CS学生要努力使scanf
表现出他们的直觉告诉他们应该这样做。现在,我将在自己的私人岛屿上退休。但是我离题了。
解决此特定陷阱的一种方法是检查scanf
是否失败,如果失败,则有目的地消耗并丢弃来自stdin
的所有输入,直到并包括下一个换行符或{{1} }, 以先到者为准。
首先让我们看一些 un 固定的代码,如果您输入非整数作为输入,则会导致无限循环:
EOF
上面的代码将(在您键入// Typing the letter 'n' and hitting <Enter> here causes an infinite loop:
int num, status;
while (1) {
printf("Enter a number: ");
status = scanf("%d", &num);
if (status == 1)
printf("OK\n");
else
printf("Invalid number\n");
}
并按n
之后),将进入无限循环,并开始一遍又一遍地喷出“无效数字”。同样,这是因为您输入的<Enter>
永远不会从输入缓冲区中清除。
有a few possible ways to get around this problem,但共识似乎是,最便携,最可靠的方法如下:
n
答案 1 :(得分:0)
函数scanf()
将返回读取的元素数,因此在这种情况下,每次读取int时将返回1,而读取char时将返回0,因此您只需要验证该返回值即可。
请记住,读取字符后它将保留在缓冲区中,因此,如果再次使用scanf()
命令,它将再次读取字符并重复错误。为避免这种情况,您需要使用while(getchar() != '\n');
考虑到这一点,我修改了您的代码,以便在引入字符并要求新的int的情况下,可以正常打印错误消息。
for (int i = 1; i <= size; i++) {
printf("Introduce the value #%d of the list: ", i);
while (!scanf("%d", &list[i])) { //verifies the return of scanf
while(getchar() != '\n'); //consumes the character in case of error
printf("What you tried to introduce is a char\n");
printf("please introduce the value #%d of the list: ", i);
}
}