5

在第 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;
}
4

2 回答 2

13

正如其他人所提到的,如果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;
}

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

实际上,如果您只想读取整数,更好的方法是不使用scanfstrtol,而是使用. 这为您提供了一个方便的指针,指向数字后面的字符,您可以检查它是空格还是 nul。

于 2013-06-02T12:01:49.027 回答
4

scanf遇到非数字时,它不会消耗任何输入并返回读取的零整数。非数字将保留在下一次调用的输入中,其scanf行为与第一次调用相同,依此类推。

在下面回答您的问题。您可以使用fgetc来解析至少一个字符,但这将为已键入的每个字符提供错误消息。通常我认为你想跳到换行符。为此,您可以fgets按照 poolie 的建议使用。或者您可以在scanf.

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

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

于 2013-06-02T11:57:27.250 回答