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)
东西和 continue
和 return
不在函数的末尾。但至少它是用 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
,而不会将其写入任何缓冲区(在格式中由 *
表示)。
已解决"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)
东西和 continue
和 return
不在函数的末尾。但至少它是用 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
,而不会将其写入任何缓冲区(在格式中由 *
表示)。