询问和控制流的状态

时间:2017-07-12 16:08:11

标签: c++ c++14

我现在正在学习C ++ Primer第4版并使用IO流。当我尝试运行书中的代码(页289)时:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    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()){
            cerr << "bad data, try again\n";
            cin.clear(istream::failbit);
            continue;
        }
        //ok to process ival
    }
}

键入字符串后我遇到了一个无限循环(比如“as”)。那么这段代码有什么问题呢?

2 个答案:

答案 0 :(得分:0)

输入字符串时,提取到ival失败,并设置 failbit 。然后你尽职地尝试清除该位并继续。但那个字符串仍在缓冲区中!所以这个行为会永远重演。

此外,you didn't actually clear the bit; you just set the stream state to failbit

您需要只调用std::cin.clear(),然后在继续之前从缓冲区中提取意外数据。

此外,while (cin >> ival, !cin.eof())是奇数;我没有检查过行为或优先级,但我想你只是写while ((cin >> ival) && !cin.eof())

总之,如果这真的是本书中的代码,那么你需要一本更好的书,因为代码在几个严肃的方面是错误的。如果您真的在编写C ++ 14,那么无论如何都需要更新的书,因为Lippman的C ++ Primer在第5版之前甚至没有更新C ++ 11。

答案 1 :(得分:0)

最后通过添加cin.ignore(INT_MAX,'\ n')使其工作。此行是必需的,因为cin.clear()仅在数据保留在缓冲区中时删除错误标志。为了清除缓冲区,需要cin.ignore。

#include <iostream>
#include <string>
using namespace std;
int main()
{
    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()){
            cerr << "bad data, try again" << endl;
            cin.clear();
            cin.ignore(INT_MAX, '\n');
        }
        //ok to process ival
    }
}