【问题标题】:Using the return value from scanf in the C programming language as a check使用 C 编程语言中 scanf 的返回值作为检查
【发布时间】:2010-12-29 10:15:00
【问题描述】:

你如何使用 scanf 的返回值来确保它是我得到的双精度值?

double input;

do {  /* do this as long as it not a double */
  printf("Input?");
  scanf("%lf", &input);
} while(scanf("%lf", &input) != 1); /* this will not work */

【问题讨论】:

    标签: c validation input


    【解决方案1】:

    scanf 将返回分配的项目数。在您的情况下,由于格式字符串仅包含%lf,因此在您获得double 的情况下,它将返回1。您的代码的问题是您首先在循环内调用scanf,这将读取流中的double。然后,在您的while 条件下,您再次调用scanf,但没有另一个double 可供读取,因此scanf 不执行任何操作。

    我编写代码的方式类似于

    int no_assigned;
    do {
        printf("Input?");
        no_assigned = scanf("%lf", &input);
    } while (no_assigned != 1);
    

    存在额外的变量是因为我觉得scanf 是应该在循环内的代码,而不是在while 条件下,但这确实是个人喜好;您可以消除额外的变量并在条件内移动(注意,移动,而不是复制)scanf 调用。

    编辑:这是使用fgets 的版本可能更好:

    double input;
    char buffer[80];
    
    do {
        printf("Input? ");
        fflush(stdout); // Make sure prompt is shown
        if (fgets(buffer, sizeof buffer, stdin) == NULL)
            break; // Got EOF; TODO: need to recognize this after loop
        // TODO: If input did not fit into buffer, discard until newline
    } while (sscanf(buffer, "%lf", &input) != 1);
    

    【讨论】:

    • +1 表示这是个人喜好。我自己更喜欢在循环中使用它,但我该判断谁?
    • 我这样做了,但我必须 fflush(stdin);在 scanf 之后或者它会永远循环(如果我把它放在 while 条件中)?
    • 不,不要这样做fflush(stdin);,因为这并不能保证你认为它会做。 scanf 确实会在输入中留下换行符。如果您将来使用scanf,那应该没关系,因为scanf 会跳过空格,但是如果您使用其他输入功能,则需要在此之前去掉换行符。事实上,更好的方法可能是在while 循环中输入一行fgets,然后在该行上使用sscanf,就像现在使用scanf 一样。
    • 好的,顺便说一句,答案很好!但是,如果你读了一些东西并把东西“放在后面”,这是否意味着你的阅读工作很糟糕?我知道你有一个替代的东西在那里,但我并不真正理解这一点。有没有一种安全的方法可以吞下包括\n在内的所有东西?
    • “更安全”的方法是我之后使用fgets 编辑的,因为fgets 读取完整的行,因此您不会在缓冲区中留下额外的换行符。 scanf 不太适合交互式输入; comp.lang.c 常见问题解答对此有一些话要说:c-faq.com/stdio/scanfprobs.html
    【解决方案2】:

    我认为这就是你想要做的:

    double input;
    
    do {  /* do this as long as it not a double */
      printf("Input?");
    } while(!scanf("%lf", &input));
    

    【讨论】:

      【解决方案3】:

      就像迈克尔说的那样,scanf() 返回一个整数,表示成功读取的元素数。据我从手册页中可以看出,您不能使用返回值来验证读取的内容是否为双精度。

      【讨论】:

        【解决方案4】:

        scanf() 将返回给定/提供的输入数。它不会返回任何数据类型相关的结果。

        【讨论】:

          【解决方案5】:

          scanf() 和朋友返回成功匹配和分配的输入项的数量。没有与类型相关的信息。但是由于您在转换字符串中指定了lf,所以您会得到一个双倍的 - 我想我错过了您的意思。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-12
            • 1970-01-01
            • 2013-04-19
            • 2012-02-02
            相关资源
            最近更新 更多