Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
验证do while循环C中的输入类型_C_Loops_Infinite Loop - Fatal编程技术网

验证do while循环C中的输入类型

验证do while循环C中的输入类型,c,loops,infinite-loop,C,Loops,Infinite Loop,基本上,我需要确保输入是一个整数,如下所示: do { printf("Enter > "); scanf("%d", &integer); } while (/* user entered a char instead of an int */); 我尝试过各种方法,但当我尝试输入char时,总是会出现运行时错误或无限循环。我知道,fflush(stdin)是一种未定义的行为,最好不要将其包含在我的代码中,以防止出现任何错误,另外由于某些原因,它在VS2015中

基本上,我需要确保输入是一个整数,如下所示:

do {
    printf("Enter > ");
    scanf("%d", &integer);
} while (/* user entered a char instead of an int */);
我尝试过各种方法,但当我尝试输入
char
时,总是会出现运行时错误或无限循环。我知道,
fflush(stdin)
是一种未定义的行为,最好不要将其包含在我的代码中,以防止出现任何错误,另外由于某些原因,它在VS2015中不再有效

以下代码是我尝试过的方法:

typedef enum {false, true} bool;
int ipt;
char c;
bool wrong_ipt;

do {
    c = '\0';
    printf("Enter > ");
    scanf("%d%c", &ipt, &c); //infinite loop occurs while a char has been entered
} while (c != '\n');

do {
    c = '\0';
    printf("Enter > ");
} while (scanf("%d", &ipt) != EOF);

do {
    wrong_ipt = false;
    do {
        ipt = NULL;
        printf("Enter > ");
        scanf("%d", &ipt);
        if (ipt == NULL) {
            wrong_ipt = true;
            break;
        }
    } while (ipt == NULL);
} while (wrong_ipt);
当用户在C中输入
char
时,除了
fflush(stdin)
之外,还有其他方法可以防止无限循环吗

谢谢

问题是“scanf()”会在输入缓冲区中留下未读数据。因此出现了“无限循环”

另一个问题是,您应该验证
scanf()
中的返回值。如果您期望一个整数值。。。而scanf返回“0”个读取项。。。那你就知道出了问题

以下是一个例子:

#include <stdio.h>

void discard_junk () 
{
  char c;
  while((c = getchar()) != '\n' && c != EOF)
    ;
}

int main (int argc, char *argv[])
{
  int integer, i;
  do {
      printf("Enter > ");
      i = scanf("%d", &integer);
      if (i == 1) {
        printf ("Good value: %d\n", integer);
      }
      else {
        printf ("BAD VALUE, i=%i!\n", i);
        discard_junk ();
      }
   } while (i != 1);

  return 0;
}

“希望有帮助

格式说明符%d告诉
scanf
命令行中需要一个整数值。当用户输入一行数据时,它将被读取为字符串,然后
scanf
尝试了解输入的字符串是否可以解释为整数的十进制数字

如果此解释成功,则找到的值将存储在作为参数传递的整数变量中

该函数以
int
值的形式检索由
scanf
执行的rigth替换次数。因为您只需要一个输入,所以值1表示一切正常

因此,如果出现错误,例如,用户输入了无效的整数,
scanf
返回的数字小于格式说明符的数量。在这种情况下,小于1的值表示发生了错误:

 int ipt, succeded;
 do {
    printf("ipt? ");
    succeded = scanf("%d", &ipt);
    if (succeded < 1) {    // Clean the input
      while (getchar() != '\n') 
        ;
    }
 } while(succeded < 1);
int ipt,成功;
做{
printf(“ipt?”);
succeed=scanf(“%d”和&ipt);
如果(成功<1){//清除输入
而(getchar()!='\n')
;
}
}而(成功<1);

您的根本错误是您从未告诉您的程序使用无效输入。换句话说,你告诉节目:

  • 如果有整数,则读取整数。(否则不读任何内容)
  • 如果没有得到整数,请返回步骤1
我猜你以为你在做的是

  • 读取输入,如果是整数,则将其存储
  • 如果不是整数,请返回步骤1
所以你需要做的是重写你的代码,让它做你想做的事情(或者想出一些其他的方法,如在另一个答案中)。也就是说,将程序编写到:

  • 读一些输入。(例如,一条线)
  • 扫描输入以查看它是否为整数,并将其存储
  • 如果不是整数,请返回步骤1

您可能会发现一些有用的相关函数有
fgets
sscanf
atoi
。(同时,尽量抵制编写错误代码的诱惑;例如,如果您打算读取一行输入,请确保您确实这样做了,并且正确无误。许多人都很懒惰,如果行很长,他们会做错误的事情;例如,只读取行的一部分,或者导致缓冲区溢出)

我知道我回答这个问题有点晚了,但您可以减少循环的使用,改用跳转语句,然后只使用一个if语句检查错误输入,仍然可以获得相同的结果

      enter: printf("Enter > ");
      i = scanf("%d", &integer);
      if (i != 1) {
        printf ("BAD VALUE, i=%i!\n", i);
        discard_junk ();
        goto enter:
      }
      printf ("Good value: %d\n", integer);

为什么不先验证输入?这有帮助吗。我不想将此列为可能的重复项,但这个问题是直接相关的。我试图在输入字符或任何无效输入后立即编写代码以再次请求新输入。抱歉,不,我正在尝试在c中创建它,而不是cppSo,
I
是存储
scanf()
返回值的bool吗,这不是一个“bool”。这是“由scanf成功匹配和分配的输入项的数量,可以少于提供的数量,如果早期匹配失败,甚至为零。”:但是
discard\u junk()
function如何清理缓冲区呢?首先,我想强调的是,“discard\u junk()”不建议用于生产代码。我只是想说明这个问题。它通过在循环中调用getchar()“直到什么都没有留下来”来“工作”。看,一种替代方法是用户(它总是读取您键入的所有内容)+现在有意义了,tythx也指出了我的错误,因为我并不真正了解
scanf()的工作原理
一旦
scanf
无法避免无限循环,您需要清除输入缓冲区。@CoolGuy:谢谢。我添加了一些清理(困扰我的是清理占用的行数比这里实际相关的行数多)。
      enter: printf("Enter > ");
      i = scanf("%d", &integer);
      if (i != 1) {
        printf ("BAD VALUE, i=%i!\n", i);
        discard_junk ();
        goto enter:
      }
      printf ("Good value: %d\n", integer);