在第5行中,我读取一个整数,isint
如果读取整数则为1,如果不是整数则为0。如果isint
为0,我有一个循环要求用户给出一个整数,我会读取,直到用户给出一个整数。我尝试这个代码给出一个字符而不是一个整数,但我有一个无限循环。该程序只是不等待提供新的输入。我的代码出了什么问题?
#include <stdio.h>
int main(void) {
int arg1;
//int arg2;
int attacknum = 1;
int isint = 1;
//printf("Insert argument attacks and press 0 when you have done this.\n");
printf("Attack %d\n", attacknum);
attacknum++;
printf("Give attacking argument:");
isint = scanf("%d", &arg1); //line 5
while(isint == 0){
printf("You did not enter a number. Please enter an argument's number\n");
isint = scanf("%d", &arg1);
printf("is int is %d\n", isint);
}
return 0;
}
答案 0 :(得分:11)
正如其他人所提到的,如果scanf
无法解析输入,则会使其保持未扫描状态。
通常scanf
因为这种行为而导致交互式输入的选择不佳,并且因为它与用户所经历的一次性界面不匹配。
最好使用fgets
将一行读入缓冲区。然后使用sscanf
解析该行。如果您不喜欢输入,请抛弃整条线并阅读另一条线。
这样的事情:
#include <stdio.h>
int main(void)
{
char line[256];
int arg1;
int isint;
while (1) {
printf("Give attacking argument:");
fgets(line, sizeof line, stdin);
isint = sscanf(line, "%d",&arg1);
if (isint) break;
printf("You did not enter a number.Please enter an argument's number\n");
}
printf("Thanks for entering %d\n", arg1);
return 0;
}
(对于生产代码,您需要处理长行,检查返回代码,还要检查数字后面的尾随垃圾等)。
实际上,如果您只想读取一个整数,而不是strtol
,那么更好的方法是不使用scanf
。这样就可以在数字后面找到一个指向字符的方便指针,你可以检查它是空格还是空格。
答案 1 :(得分:4)
当scanf
遇到非数字时,它不会消耗任何输入并返回读取的零整数。非数字将保留在输入中,以便下一次调用scanf
,其行为与第一次调用相同,等等。
回答下面的问题。您可以使用fgetc
来解析至少一个字符,但这会为已键入的每个字符提供错误消息。通常我认为你想跳过换行符。为此,您可以使用poolie建议的fgets
。或者您可以在scanf
之后添加以下内容。
int ch;
if (isint == 0)
while ((ch = fgetc(stdin)) != EOF && ch != '\n')
{
/* Skip characters */
}
P.S:在你的情况下,最好把它放在循环中的第一个printf
之前。