为什么scanf在无效输入上陷入无限循环?

在第5行中,我读取一个整数,如果它读取整数,则isint为1,如果不是整数, isint 0。 如果isint为0,我有一个循环要求用户给出一个整数,我会读取,直到用户给出一个整数。 我尝试这个代码给出一个字符而不是一个整数,但我有一个无限循环。 该程序只是不等待提供新的输入。 我的代码出了什么问题?

 #include  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; } 

正如其他人所提到的,如果scanf无法解析输入,则会使其无法扫描。

通常, scanf是交互式输入的不良选择,因为这种行为,并且因为它与用户经历的一次一行界面不匹配。

最好使用fgets一行读入缓冲区。 然后使用sscanf解析该行。 如果您不喜欢输入,请抛弃整条线并阅读另一条线。

像这样的东西:

 #include  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 。 这样就可以在数字后面找到一个方便的指向字符的指针,你可以检查它是空格还是空格。

scanf面临非数字时,它将不消耗任何输入并返回读取的零整数。 非数字将保留在下一次调用scanf的输入中,该调用的行为与第一次调用相同,等等。

在回答你的问题如下。 您可以使用fgetc来解析至少一个字符,但这会为已经键入的每个字符提供错误消息。 通常我认为你想跳过换行符。 为此,您可以使用poolie建议的fgets。 或者您可以在scanf之后添加以下内容。

 int ch; if (isint == 0) while ((ch = fgetc(stdin)) != EOF && ch != '\n') { /* Skip characters */ } 

PS:在你的情况下,最好把它放在循环中的第一个printf之前。