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

Dch*_*ris 4 c scanf stdio

在第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;
}
Run Code Online (Sandbox Code Playgroud)

poo*_*lie 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;
}
Run Code Online (Sandbox Code Playgroud)

(对于生产代码,您需要处理长行,检查返回代码,还要检查数字后面的尾随垃圾等)

实际上,如果你只想读取整数,而不是使用,那么更好的方法就是scanf使用strtol.这样就可以在数字后面找到一个方便的指向字符的指针,你可以检查它是空格还是空格.