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

时间:2012-11-30 18:34:17

标签: 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');
    }

所以:

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

    异常掩码是所有流对象的内部值   指定哪些状态标志必须抛出异常   组

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

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

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

    如果要删除

            in.exceptions ( ifstream::failbit | ifstream::badbit );
    

    它有效。


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

1 个答案:

答案 0 :(得分:7)

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

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