【发布时间】:2021-10-17 19:10:19
【问题描述】:
我正在学习 C,但在运行此循环时遇到了问题。我写了一个while 循环来提示用户输入包裹和数量。我尝试验证要检查的数量的输入是否为整数(当用户键入字符时,它会提示用户再次键入)
第一次运行,一切都很好。
但是当循环第二次运行等时,我尝试输入一个字符作为包裹的数量,不会弹出消息告诉用户再次输入。
scanf 的值被忽略,tempQtty 的值等于用户之前键入的数量。
有没有办法解决这个问题,或者有其他方法可以验证用户输入是否为整数?
抱歉我的英文不好:")[输入、预期输入和实际输入][1]
while(skip != 'x')
{
printf("\n\n%27sPACKAGE A/B/C/D ( x = skip ) : ", "");
rewind(stdin);
package = getchar();
switch (package)
{
case'x':case'X': skip = tolower(package); break;
case'A':case'a':case'B':case'b': case'C':case'c':case'D':case'd':
printf("%27sQUANTITY%21s: ", "", "");
rewind(stdin);
scanf("%d", &tempQtty); //here's the problem
while (tempQtty < 0)
{
printf("%27s(PLEASE KEY IN A CORRECT VALUE!)\n", "");
printf("%27sQUANTITY%21s: ", "", "");
rewind(stdin);
scanf("%d", &tempQtty);
}
switch (package)
{
case 'A':case 'a': qttyA = tempQtty; totalQttyA += tempQtty; break;
case 'B':case 'b': qttyB = tempQtty; totalQttyB += tempQtty; break;
case 'C':case 'c': qttyC = tempQtty; totalQttyC += tempQtty; break;
case 'D':case 'd': qttyD = tempQtty; totalQttyD += tempQtty; break;
}
break;
default:
printf("%27s(NO SUCH PACKAGE! PLEASE KEY IN AGAIN!)\n", "");
}
}
printf("\nA = %d", qttyA);
printf("\nB = %d", qttyB);
[1]: https://i.stack.imgur.com/hBD82.png
【问题讨论】:
-
请给出准确的输入、预期结果和实际结果。如果你的意思是你输入一个需要整数的字符,那么这是行不通的。
scanf会返回失败,输入数据不会被消费。您需要始终检查scanf的返回值。此外,scanf也不是很好,如果输入可能是错误的,因为不正确的输入不会被读取。而是使用fgets和sscanf。 -
getchar在做什么? -
@DWei 这是一个令人惊讶的难题,尤其是如果您坚持使用
scanf进行输入。您必须做两件事: (1) 检查 scanf 的返回值:如果它没有返回 1,则表示它没有成功读取您要求它读取的值。 (2) 如果scanf失败——如果它返回小于1——你必须以某种方式丢弃错误的输入。 (更多内容在下一条评论中。) -
@DWei 所以你想在调用
scanf之后尝试“刷新”错误或未读的输入。在您遇到这个问题之前,很多很多人都遇到过这个问题,并且关于它的答案有很多很多。不幸的是,在所有这些答案中,我没有找到一个好的、“规范”的答案来指向你。但是,如果您搜索“scanf flush input”,您会找到答案——只需忽略任何建议使用fflush(stdin)的内容,这是错误的。 (您也可以忽略所有解释为什么fflush(stdin)是错误的,因为您已经知道了。寻找解释使用什么的答案。) -
@DWei 但我有一个替代的,有点异端的建议给你。虽然尝试检查用户是否意外输入了“错误”输入,并尝试提示用户重试是一个崇高的目标,但事实证明,
scanf基本上没有这种用途 .使用scanf编写好的代码来获取用户输入、检查其有效性并在必要时重新提示用户太难了。这太难了,我相信它不值得。有关详细信息,请参阅this answer。