我一直在学习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;
}
答案 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,当给定越界数字,文件结束,流失败或无效字符时,这不会进入无限循环。