【问题标题】:Verifying Input in C验证 C 中的输入
【发布时间】:2016-10-07 20:44:05
【问题描述】:

我正在尝试编写一个简单的二进制计算器来重新熟悉 C。由于某种原因,第一次输入验证工作正常,即使数字的第二次验证以几乎相同的方式编写,如果用户输入错误的输入,while 循环只是无限循环,而无需等待新的用户输入。这是代码,感谢您的帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  char operator[20];
  char valid_operator[4] = "+-*/";
  printf("Enter operator: ");
  scanf("%s", operator);
  printf("You entered: %s\n", operator);
  while(strchr(valid_operator, (int)operator[0]) == NULL) {
    printf("%s is not a valid operator.  Enter +, -, /, or *: ", operator);
    scanf("%s", operator);
  }

代码一直运行到这里。如果用户第一次输入错误的输入,则下一部分将陷入无限循环。重新提示永远不会发生。

  int input1;
  int input2;
  printf("Enter the two inputs (separated by whitespace): ");
  int num_ints = 1;
  num_ints = scanf("%d %d", &input1, &input2);
  printf("Input 1: %d.  Input 2: %d.\n", input1, input2);
  while(num_ints < 2){
    printf("Invalid input.  Enter two integers separated by whitespace: ");
    num_ints = 0;
    num_ints = scanf("%d %d", &input1, &input2);
    printf("Input 1: %d.  Input 2: %d.\n", input1, input2);
  }
  return 0;

【问题讨论】:

  • 使用 fgets 从键盘读取,使用 sscanf 从字符串中提取
  • strchr(valid_operator, ...) 将不起作用,因为它的定义缺少 \0 终止符,这对于字符串操作至关重要。试试char valid_operator[] = "+-*/"; 因为你将它的大小限制为4 数组中没有终止符。
  • char valid_operator[4] - 你没有分配空终止符?将其更改为 const char* valid_operator = "+-*/";
  • 不测试 scanf 的返回值是在寻求惊喜。
  • 无效输入 "t" 停留在输入缓冲区中无论您使用scanf 格式说明符scanf 多少次。解决这个问题的最简单方法是输入带有fgets 的字符串,然后当该字符串上的sscanf 失败时,您可以轻松获得新的输入。

标签: c input integer


【解决方案1】:

无限循环而无需等待新用户输入的原因是,当scanf 无法读取请求格式的字符时(在您的情况下为%d它赢了'不推进文件指针,在循环的下一次迭代中,它将尝试再次读取相同的错误字符。

这与 POSIX 一致:http://pubs.opengroup.org/onlinepubs/009695399/functions/fscanf.html

如果比较表明它们不相等,则指令将失败,不同和后续字节应保持未读

另外,从man scanf返回值:

...返回成功匹配和分配的输入项的数量,可以少于提供的数量,如果早期匹配失败,甚至为零。

所以,你最好将fgetssscanf 结合起来。

do {
    char buf[BUFSZ];
    printf("Enter the two inputs (separated by whitespace): ");
    if(fgets(buf, BUFSZ, stdin) == NULL)
    {
        /* Error exit. */
        break;
    }
    num_ints = sscanf(buf, "%d %d", &input1, &input2);
} while(num_ints != 2);

【讨论】:

  • fgets 的结果也应该检查,但是 +1。
【解决方案2】:

您需要清除标准输入。如果您在示例“1 t”中输入非整数,则不会消耗“t”(留在流中)。将此添加到您的循环中:

while(num_ints < 2){
   while (fgetc(stdin) != '\n'); // clear input
. . .

请参阅 C program loops infinitely after scanf gets unexpected data 以获得对该问题的详细说明。

【讨论】:

  • 啊我怀疑发生了这样的事情。这解决了这个问题。我仍然不明白为什么在第一种情况下会消耗错误的输入,而在第二种情况下则不会。
猜你喜欢
  • 2012-10-11
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多