【问题标题】:Is it possible to validate input with scanf?是否可以使用 scanf 验证输入?
【发布时间】:2021-04-05 17:28:34
【问题描述】:

我正在尝试检查输入中是否有字母,如果有,请重复 scanf 函数(特别是在案例 1 的 switch 语句之后)。

它能够检测单个字符,如果输入一个字符,变量保持为0。 但是,如果输入了一个数字和一个字符,它将接受该数字并忽略该字符。 这是主要问题。

想知道过滤用户是否输入字母以要求用户重新输入数字的可能方法。

    while (true) {
        printf("Enter code 1 :");

        number = 0;
        scanf_s("%d", &number);
        if (number == 0) {
            // find the new line to recieve new input
            while (fgetc(stdin) != '\n');
        }

        switch (number) {
        case 1:
            managers = 0; 
            printf("Managers\n");

            while (managers == 0) {
                managers == 0;
                scanf_s("%lf", &managers);

                if (managers == 0) {
                    managers == 0;
                     (printf("You have not enterd a number\n")),(fgetc(stdin) == '\n',managers==0, scanf_s("%lf", &managers));

                }
            }
            printf("Managers have this much %.2f.\n", managers);
            break;

        default:
            printf("Invalid entry please enter 1 or 2.");
            break;
        }

    }
}```

【问题讨论】:

  • 检查 scanf 返回的值。这是很好的信息。
  • man scanf?实际上,只需检查 scanf 返回值即可。

标签: c validation scanf


【解决方案1】:

是否可以使用 scanf 验证输入?

对于良好的输入和一些错误的输入,可以验证,但一般情况下,无法使用scanf() 验证输入。

... 或者如果转换的结果无法在对象中表示,则行为未定义。 C17dr § 7.21.6.2 10

对于scanf_s("%d", &number);,如果文本数字输入超出int 范围,结果是未定义行为 (UB)。 scanf_s("%lf", ...);也可能是UB

最好的方法是使用fgets() 读取用户输入的,然后使用strtol() 和朋友来验证字符串


一个好的输入设计细节,当输入很好时应该如何处理错误输入。

注意,由于stdin 上的文件结束,下面的 OP 代码将导致fgetc() 返回EOF 的无限循环。

if (number == 0) {
    // find the new line to receive new input
    while (fgetc(stdin) != '\n');
}

【讨论】:

  • 您能举例说明 srtrol 和 fgets 的用法吗?
  • @TheodoreVassilakoglou Sample.
【解决方案2】:

因为 scanf(3) 不会读取它无法解码的内容,所以对于不确定的输入(不是由机器产生的)更容易先读取输入,然后用 sscanf(3)。这为您提供了一个一致的 read-evaluate-process 循环 (tm)。

不要测试 scanf(或任何函数,真的)的参数以确定它是否有效。查看返回码。 scanf 返回它处理的参数的数量,它告诉你它取得了什么样的成功。

如果您需要,您可以添加一个%n 参数(您需要检查)告诉您处理了多少个字符。比如你的用户可以输入12 dozen eggs,scanf会将12读入managers,返回1,表示成功。但是您可能还需要处理其他未处理的输入。通过先读取整行,然后扫描它,输入 stream 不会被阻塞,应用程序可以确定如何处理任何无效输入。

【讨论】:

    猜你喜欢
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多