当异常掩码未设置为 eofbit 时,为啥 getline() 会抛出“std::ios_base::failure”?

Posted

技术标签:

【中文标题】当异常掩码未设置为 eofbit 时,为啥 getline() 会抛出“std::ios_base::failure”?【英文标题】:Why getline() throws 'std::ios_base::failure' when exception mask is not set to eofbit?当异常掩码未设置为 eofbit 时,为什么 getline() 会抛出“std::ios_base::failure”? 【发布时间】:2012-11-19 00:26:23 【问题描述】:

考虑以下代码:

    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');
    

所以:

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

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

我没有设置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】:

问题在于您的输入迭代。 eofbit 仅在最后一次读取到达 EOF 时设置,如果下一次读取将仅读取 EOF,则不会设置。当后者发生时,failbit 同时被设置。见讨论here。

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

【讨论】:

好的,但是我 clear()-ed 异常掩码,为什么它似乎仍然处于活动状态? @Razorfever 没有clean() 成员,我假设您的意思是clear()。这会清除状态位(eofbitfailbitbadbit),但不会影响异常掩码。 是的,我使用了 clear() 抱歉 [已在 Q 中修复]。可能是与该问题相关的最后一个问题:有什么方法可以返回到设置异常掩码之前的状态? 如果没有抛出异常,最后一个getline()(设置failbit的那个)将清除s,你将处理一个空字符串(将"\n"推入@987654337 @) 这从来不是输入的一部分。换句话说,你得到的是虚假数据。 值得一提的是要使用的正确循环形式:while (getline( in, s )) boost::algorithm::trim(s); lns.push_back( s+='\n');

以上是关于当异常掩码未设置为 eofbit 时,为啥 getline() 会抛出“std::ios_base::failure”?的主要内容,如果未能解决你的问题,请参考以下文章

iphone ios 7 主屏幕掩码未正确应用于我的图标

为啥设置 DataSource 时 ComboBox 不抛出异常?

为啥当参数为null时,postgres会抛出异常?

为啥这个声音循环不会停止?

当 OPTIONS 请求的 statusCode 为 200 时,为啥我会在 API Gateway GET 请求中收到 CORS 错误?

掩码设置为0时不生成核心文件