为什么是无限循环

时间:2013-08-08 19:49:11

标签: c++ infinite-loop

我一直在学习C ++,而这段代码来自一个简单的评分程序。但是当我尝试获取用户输入时,就会出现问题。 如果我输入一个数字,无论是小于0还是大于100,或介于两者之间,我的循环工作正常。 但是如果我输入任何字母或任何非字母数字字符(例如:+,(,%等)),我将永远打印出“请输入0到100之间的等级值”的无限循环。 我做错了什么?

感谢。

int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

int grade = -1; // grade will hold grade value; initialized to -1
do {
    cout << "Please enter a grade value between 0 and 100." << "\n";
    cin >> grade;
} while (grade < 0 || grade > 100);

cout << grade << "\n";

printGrade(grade);

return 0;
}

4 个答案:

答案 0 :(得分:2)

如果cin>>grade失败(也称为无法解析为int),则不会消耗流。你可以尝试:

int main()
{ using namespace std;

int grade = -1; // grade will hold grade value; initialized to -1
do {
    cout << "Please enter a grade value between 0 and 100." << "\n";
    if (!(cin >> grade))
    {
      cin.clear();
    }
} while (grade < 0 || grade > 100);

cout << grade << "\n";

return 0;

}

但这只是问题的一部分。实际上,你应该使用std :: getline并将等级解析为正确的输入。

答案 1 :(得分:1)

如果cin没有收到数据类型(int)的有效输入,则变量等级不会更改并保持为-1。您可以测试输入是否成功

bool success = (cin >> grade);
if (! success)
{
    cin.clear();
    cout << "bad input\n";
    break;
}

您也可以将其用作快捷方式if (! (cin >> grade))

请注意,在再次使用错误状态clear之前,您需要cin

答案 2 :(得分:1)

我很确定cin失败了所以你可能需要重置其失败标志或类似的东西。

将此添加到您的循环中:

if (cin.fail())
{
    cout << "failed";
    cin.clear();
}

答案 3 :(得分:1)

正确而安全地阅读,直到您获得有效的输入,这比您想象的要复杂得多。如果输入无效(如字母),则将流设置为“失败”状态,并在您清除状态之前拒绝再读取任何字符。但即使你清除状态,那个输入仍然在那里等待。所以你必须忽略这些角色。最简单的做法是在下一个输入键之前忽略所有内容,然后再次尝试输入。

但它变得更加复杂,因为如果流有错误,它被设置为“坏”状态,或者如果它到达流的末尾,它将被设置为“eof”状态。这两者都不可恢复,因此您必须检测它们并退出程序以避免无限循环。即使更多令人恼火,istream也有.fail()功能,但会检查它是否在fail bad中,这几乎使它成为invalid_input在我看来没用。所以我写了一个get_grade来检查流是否可以继续。

请注意,如果输入超出范围,fail会手动设置#include <iostream> #include <stdlib.h> #include <limits> bool invalid_input(std::istream& in) {return in.rdstate() == std::ios::failbit;} std::istream& get_single_grade(std::istream& in, int& grade) { std::cout << "Please enter a grade value between 0 and 100." << "\n"; if (in>>grade && (grade<0 || grade>100)) in.setstate(std::ios::failbit); return in; } bool get_grade(std::istream& in, int &grade) { while(invalid_input(get_single_grade(in, grade))) { //while we failed to get data in.clear(); //clear the failure flag //ignore the line that the user entered, try to read the next line instead in.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); } return in.good(); } int main(int argc, char* argv[]) { int grade = -1; // grade will hold grade value; initialized to -1 if (get_grade(std::cin, grade) == false) { std::cerr << "unxpected EOF or stream error!\n"; return false; } std::cout << grade << "\n"; return EXIT_SUCCESS; } 标记。

{{1}}

正如您所看到的here,当给定越界数字,文件结束,流失败或无效字符时,这不会进入无限循环。