我在一本书中找到了这个代码片段:
int ival;
// read cin and test only for EOF; loop is executed even if there are other IO failures
while (cin >> ival, !cin.eof()) {
if (cin.bad()) // input stream is corrupted; bail out
throw runtime_error("IO stream corrupted");
if (cin.fail()) { // bad input
cerr<< "bad data, try again"; // warn the user
cin.clear(istream::failbit); // reset the stream
istream::iostate cin_state = cin.rdstate();
continue; // get next input
}
// ok to process ival
}
如果我在命令窗口中单击“f”,则无数“坏数据,再试一次”,cin_state为0X02,等于badbit。 Failbit还不清楚,为什么?
答案 0 :(得分:6)
问题是f
永远不会从输入流中删除,因此cin >> ival
会不断尝试一遍又一遍地阅读它。
你需要跳过它。例如,请参阅How does istream::ignore( ) work?
答案 1 :(得分:1)
虽然NPE关于不从流中删除违规数据的观点是正确的,但它并不是唯一(或最令人震惊的)问题。
由于默认参数,您应该使用cin.clear()
,它与cin.clear(ios_base::goodbit)
相同。正如您在评论中推测的那样,cin.clear(istream::failbit)
不会将cin
重置为良好状态。事实上,它将流设置为失败状态。这似乎违反直觉,但clear
将流的状态设置为(或“清除它”)传递的参数。关于其操作还有一些其他细节,但它们与此讨论没有密切关系。
请务必在clear
之前致电ignore
,否则后者将无效。最后,要防止任意长的无效条目,请将std::numeric_limits<int>::max()
传递给ignore
作为第一个参数。
修改后的代码片段应为:
int ival;
// read cin and test only for EOF; loop is executed even if there are other IO failures
while (cin >> ival, !cin.eof()) {
if (cin.bad()) // input stream is corrupted; bail out
throw runtime_error("IO stream corrupted");
if (cin.fail()) { // bad input
cerr<< "bad data, try again"; // warn the user
cin.clear(); // or cin.clear(istream::goodbit);
istream::iostate cin_state = cin.rdstate();
cin.ignore(std::numeric_limits<int>::max(), '\n');
continue; // get next input
}
// ok to process ival
}
至于你为什么在C ++ Primer中找到这个,我不能说。我没有看过这本书,但我知道这个很好。我建议您查看您的版本的年龄,并查找勘误列表。