为什么当异常掩码未设置为eofbit时,getline()会抛出'std :: ios_base :: failure'?

Raz*_*ver 8 c++ exception getline

请考虑以下代码:

    ifstream in;
    try {
        in.exceptions ( ifstream::failbit | ifstream::badbit );
        in.open(pConfLocation);
    } catch ( ifstream::failure e ) {
        throw std::runtime_error("Can't open configuration file\n");
    }

    vector<string> lns;
    string s;

    in.clear();
    while ( !in.eof() ){
        getline( in, s );
        boost::algorithm::trim(s);
        lns.push_back( s+='\n');
    }
Run Code Online (Sandbox Code Playgroud)

所以:

  1. 我为try-catch块的需要设置了以下"异常掩码"(ifstream :: failbit | ifstream :: badbit).该文件打开没有问题.
  2. 在while {}块中,我知道在文件末尾将设置eofbit.

异常掩码是所有流对象的内部值,指定哪些状态标志在设置时必须抛出异常.

我没有设置ifstream :: eofbit,但无论如何在运行时出现以下错误:

terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_ios::clear
The program has unexpectedly finished.
Run Code Online (Sandbox Code Playgroud)

我无法理解这种行为.我试图在{}之前使用in.clear()但没有效果.clear()本身设置goodbit,据我所知,"flags必须抛出异常"(参见上面的引用),但是当googbit设置时它不会导致抛出任何异常......

如果要删除

        in.exceptions ( ifstream::failbit | ifstream::badbit );
Run Code Online (Sandbox Code Playgroud)

有用.


如何让getline()在这种情况下工作?

Rei*_*ica 7

问题出在输入迭代中.eofbit仅在最后一次读取达到EOF时设置,而不是在下一次读取只读取EOF时设置.当后者发生时,failbit同时设置.请参阅此处的讨论.

在您的特定情况下,如果文件以换行符结束(可能如此),则getline()读取并包括该换行符并返回.eofbit仍未设定.接下来getline()会直接遇到EOF,并且根据其文档,"如果函数不提取任何元素,则调用它setstate(failbit)."

  • 值得一提的是使用正确的循环形式:`while(getline(in,s)){boost :: algorithm :: trim(s); lns.push_back(s + ='\n'); }` (2认同)