已解决“在输入正确值后循环后错过了返回”
我使用scanf_s从控制台获取输入。我写了一个检查输入的函数,如果它错了,它再次请求输入。
如果我第一次输入正确的值,一切都很好。如果我必须在funktion中第二次输入值,一切都很好,但是如果返回这个值,则功能返回NaN。为什么只有当我使用scanf_s两次时,双值才会丢失?
如果我调用输入并输入正确的值,则返回double。如果我输入的值小于或等于0,我必须再次输入值,但这次返回NaN。调试时我可以看到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;
}
}
答案 0 :(得分:1)
您不会在if (eingabe <= 0.0)
内返回值。
您必须重新编写代码,因此将始终返回eingabe。
像这样:
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;
}
}
答案 1 :(得分:0)
我认为您的解决方案中有一些问题需要讨论。
首先,并非所有控制路径都返回一个值,这可能会导致函数input
的不良结果;你的编译器应该警告过你。
其次,您的错误条件基于用户输入的双值,即负数或0
被视为错误。如果你想输入负数或0,那么这种方法必须重新设计。您应该使用scanf
的返回值,它可以指示是否已成功读取指定的格式。
第三,你使用scanf_s
,即&#34; secure&#34;版本scanf
,scanf_s
可以限制写入缓冲区的字符;这有两个原因没有意义:(a)您没有提供缓冲区限制作为附加参数,(b)扫描%lf
无论如何都受数据类型double
的限制。例如,scanf_s
- 参考msdn:
与scanf和wscanf不同,scanf_s和wscanf_s需要缓冲区大小 要为c,C,s,S或string类型的所有输入参数指定 包含在[]中的控件集。字符的缓冲区大小在指向缓冲区或变量
的指针后立即作为附加参数传递
第四,构造可能有点复杂,例如,double eingabe = 0.0
后跟if (eingabe <= 0.0)
的语句没有多大意义。
所以,让我提出一个更短的&#34;函数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
,而不将其写入任何缓冲区(格式为*
表示)。