c++ 函数 returns nan 而不是 double

c++ function returns nan instead of double

已解决"missed the return after the loop after a correct value was entered"

我使用 scanf_s 从控制台获取输入。我写了一个检查输入的函数,如果输入错误,它会请求重新输入。

如果我第一次输入正确的值,一切都很好。如果我必须在函数中第二次输入值,一切都很好,但是 returning 这个值是函数 returns NaN。为什么仅当我使用 scanf_s 两次时 return 中的双精度值才丢失?

如果我调用输入并输入正确的值,则会 return 编辑一个双精度值。如果我输入一个小于或等于 0 的值,我必须再次输入该值,但这次 NaN 是 returned。在调试时我可以看到 eingabe 仍然是双倍的。

double input() {
    int n = -1;
    double eingabe = 0.0;

    scanf_s("%lf", &eingabe);

    clearBuffer();
    if (eingabe <= 0.0)
    {
        do
        {
            printf("Invald input");
            printf("Try again: ");

            n = scanf_s("%lf", eingabe);
            clearBuffer();
        } while (eingabe <= 0.0);
    }
    else
    {
        return eingabe;
    }
}

void clearBuffer() {
    //alles aus dem Buffer lesen bis man bei EOF (END OF FILE) ankommt
    int c;
        while ((c = getchar()) != EOF) {
            if (c == '\n')
                break;
        }
}

您没有 return if (eingabe <= 0.0) 中的值。

您必须重新编写您的代码,因此将始终 return 编辑代码。

像这样:

if (eingabe <= 0.0)
{
    do
    {
        printf("Invald input");
        printf("Try again: ");

        n = scanf_s("%lf", &eingabe);
        clearBuffer();
    } while (eingabe <= 0.0);
}
return eingabe;

或者像这样:

if (eingabe <= 0.0)
{
    do
    {
        printf("Invald input");
        printf("Try again: ");

        n = scanf_s("%lf", &eingabe);
        clearBuffer();
    } while (eingabe <= 0.0);
    return eingabe;
}
else
{
    return eingabe;
}

在我看来,第一种情况更好。

编辑

这里我用你的代码做了一些重构。不是每个人都会喜欢它,因为 while(true) 东西和 continuereturn 不在函数的末尾。但至少它是用 C++ 编写的,在我看来它非常自然并且读起来很清楚。

#include <iostream>
#include <limits>

double input() {
    double eingabe;

    while (true) {
        std::cout << "Enter a positive real number: ";
        std::cin >> eingabe;

        if (std::cin.fail()) {
            std::cout << "Number expected." << std::endl;
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            continue;
        }

        if (eingabe <= 0) {
            std::cout << "Positive number expected." << std::endl;
            continue;
        }

        return eingabe;
    }
}

我认为您的解决方案中有一些问题需要讨论。

首先,并不是所有的控制路径都return一个值,这很可能导致函数input出现不希望的结果;你的编译器应该警告过你。

其次,您的错误条件基于用户输入的双精度值,即负数或 0 被视为错误。如果您还想输入负数或 0,则必须重新设计此方法。你应该使用scanf的return值,它可以指示指定的格式是否已被成功读取。

第三,您使用 scanf_s,即 scanf 的 "secure" 版本,因为 scanf_s 可以限制写入缓冲区的字符;这在这里没有意义,原因有两个:(a) 您没有为缓冲区提供限制作为附加参数,以及 (b) 扫描 %lf 无论如何都受到数据类型 double 的限制。例如,scanf_s-reference on msdn:

Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable

第四,结构可能有点复杂,例如,语句 double eingabe = 0.0 后跟 if (eingabe <= 0.0) 没有多大意义。

所以让我提出一个 "shorter" 函数的解决方案 input:

double input() {

    double eingabe = 0.0;
    int validInput = 0;
    do {
        if (scanf("%lf", &eingabe) == 1 && eingabe > 0)
            validInput = 1;
        else {
          printf("Invald input\n"
                "Try again:");
          scanf("%*[^\n]\n");
        }
    }
    while (!validInput);
    return eingabe;
}

请注意,语句 scanf("%*[^\n]\n") 会消耗任何字符,直到下一个 \n 包括 \n,而不会将其写入任何缓冲区(在格式中由 * 表示)。