数据不好,再试一次

Bad data, try again

本文关键字:一次 数据      更新时间:2023-10-16

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

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

问题是f从未从输入流中删除,因此cin >> ival一直试图一遍又一遍地读取它。

你需要跳过它。例如,istream::ignore()是如何工作的?

虽然NPE关于不从流中删除违规数据的观点是正确的,但这并不是唯一(或最严重)的问题。

您应该使用cin.clear(),由于默认参数,它与cin.clear(ios_base::goodbit)相同。正如你在评论中推测的那样,cin.clear(istream::failbit)不会将cin重置为良好状态。实际上,将流设置为失败状态。这似乎违反直觉,但是clear将流的状态设置为(或"清除为")传递的参数。关于它的操作还有其他一些细节,但它们与本文讨论无关。

确保在ignore之前调用clear,否则后者将不起作用。最后,为了防止任意长的无效条目,将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中找到这个,我不能说。我没有读过这本书,但我知道它写得很好。我建议你检查一下你的版本有多旧,并查找一个勘误表。