【问题标题】:Validation check with scanf does not work inside a loop使用 scanf 的验证检查在循环内不起作用
【发布时间】:2018-06-09 06:50:21
【问题描述】:

我正在尝试创建一个功能来检查用户的输入,并让他们在输入错误类型的输入时再试一次。

因此,当我在函数中输入错误的输入时,它会将我置于无限循环中。我能做些什么来修复它?

我只能使用getcharscanf 进行用户输入。

int sizeOfField()
{
    int size,inputCheck,flag=0;

    while (!flag)
    {
        inputCheck= scanf(" %d ", &size );
        if ( inputCheck < 1 )
        {
            printf( "Invalid Input!\n" );
            printf( "Try agian");
        } else if (inputCheck == 1)
            flag=1;
    }
    return size;
}

【问题讨论】:

  • 清除stdin。但是再次正确地做很多工作。为什么不fgetsstrtol
  • 你能重新格式化你的代码并检查你的括号吗?目前尚不清楚您是否在 while 循环中过早地执行了返回。
  • 您输入的“错误输入”是什么?从代码中,你做了这样的事情,如果 scanf 失败,再次等待下一个输入 - 我想,它会一直循环,直到你给出正确的输入..
  • 这就是我想要的......但是 scanf 出于某种原因只工作一次,它使程序在循环中无限运行

标签: c validation while-loop integer scanf


【解决方案1】:

只允许使用 getchar 和 scanf 进行用户输入。

使用fgets() 会更好。但是要忍受这种限制....


scanf(" %d ", &amp;size ); 返回 0 时,非数字输入仍保留在 stdin 中。

代码需要使用无效输入 - OP 的代码中缺少该输入。

为了保持一致性,即使输入良好,也要消耗该行的其余部分。此代码不会检测在同一行的正确输入之后是否存在尾随垃圾。

" %d " 中的第二个空格也是个问题。 " " 指示 scanf() 读取所有空白,直到检测到一些非空白。这意味着scanf(" %d ", &amp;size ); 在输入类似"123\n4\n" 之前不会返回。 4 被读取,确定不是 空白 并放回以供以后输入。从格式中删除尾随空格。

如果输入返回 EOF(文件结束或罕见的输入错误),代码也会出现问题。函数sizeOfField() 无法传达文件结尾。函数可以重新定义,或者暂时退出程序。

int sizeOfField(void) {
  int inputCheck;

  do {
    int size;
    inputCheck = scanf("%d", &size);
    if (inputCheck == EOF) {
      break;
    }

    // consume rest of line
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);

    if (inputCheck == 1) {
      return size;
    }

    if (ch == EOF) {
      break;
    }

    // Non-numeric input occurred.
    printf("Invalid Input!\n" "Try again");
    fflush(stdout);
  }

  // No recovery possible
  exit(EXIT_FAILURE);  
}

奇怪的是,这是" %d" 优于"%d" 的情况。当输入为非数字时,代码确定至少所有前导空格(包括'\n')都已被消耗。如果需要将多个字符“放回”到stdin 中,则有关由于在stdin 中的非数字而将哪些租船人放回的规范是有问题的。如果没有这种保证,while ((ch = getchar()) != '\n' &amp;&amp; ch != EOF); 可能不会消耗所有有问题的非数字输入。

【讨论】:

  • AFAIU 最后一段 - 如果我们使用 "%d" 然后输入 \nX 然后 scanf 由于非数字输入而失败 X - 不确定它是否会放回结果只有X\nX - 当我们在那之后尝试清除stdin 它会消耗\n。然后再次遇到问题。这是你的意思吗?
  • 我很好奇您的“奇怪”评论。由于%d 跳过前导空白,就像空白跳过空白一样,空格是无害但不必要的添加 - 与您想说的相反,它没有任何好处。
  • @JonathanLeffler 也许吧。使用scanf("%d",... 并输入"\tx" 转换失败,scanf() 返回 0。指定的getchar() 返回值是多少? 'x''\t'?
  • 必须是x。输入无条件地跳过前导空白。空格不会导致转换失败。另见Is it possible for fscanf() to return zero and consume input at the same time?
  • 如果您遇到的系统返回选项卡而不是x,那么是的,您遇到了一个有错误的系统。浮点转换和1.23E+N 变得更有趣; N 不是数字的一部分,但 E 和 + 不能使用,因为 N 出现的地方没有数字。 BSD (macOS) 有 getchar() 返回 E; Linux (IIRC) 返回 N。就严格的标准一致性而言,该错误在 BSD/macOS 中;从理智和感性上来说,BSD是理智的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 2015-01-04
  • 2020-04-16
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多