数据不好,请再试一次

时间:2013-04-05 09:17:07

标签: c++

我在一本书中找到了这个代码片段:

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还不清楚,为什么?

2 个答案:

答案 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中找到这个,我不能说。我没有看过这本书,但我知道这个很好。我建议您查看您的版本的年龄,并查找勘误列表。