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

Why getline() throws 'std::ios_base::failure' when exception mask is not set to eofbit?

本文关键字:std ios failure base getline 异常 掩码 eofbit 设置 为什么      更新时间:2023-10-16

考虑以下代码:

ifstream in;
try {
in.exceptions ( ifstream::failbit | ifstream::badbit );
in.open(pConfLocation);
} catch ( ifstream::failure e ) {
throw std::runtime_error("Can't open configuration filen");
}
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。但是

异常掩码是所有流对象的内部值指定哪些状态标志在设置。

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

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

我不能理解这种行为。我试图在.clear()中使用,就在之前,而{},但没有效果。clear()本身设置goodbit,据我所知,"flags必须抛出异常"(参见上面的引用),但当googlebit

如果要删除

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

它是有效的。


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

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

在您的特定情况下,如果文件以换行符结尾(可能是这样),则getline()读取该换行符并返回。CCD_ 4仍然没有被设置。然后,下一个getline()直接遇到EOF,根据其文档,"如果函数不提取元素,它将调用setstate(failbit)。">