【问题标题】:How to make getline play nice with ios::exceptions?如何使 getline 与 ios::exceptions 一起玩得很好?
【发布时间】:2023-03-07 21:23:01
【问题描述】:

我正在尝试使用 ifstream,我需要能够使用 getline 进行循环,但希望使用 ios::exceptions 抛出异常:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream f;
    f.exceptions( std::ifstream::failbit | std::ifstream::badbit );

    try {
        f.open("data/all-patents.dat", std::ifstream::in);
    }
    catch (std::ifstream::failure e) {
        std::cout << "Caught exception opening: " << e.what() << "\n";
    }
    
    std::string l;
    while (!std::getline(f, l).eof()) {
        // do something
    }

}

但是当getline遇到EOF时,会抛出异常:

terminate called after throwing an instance of 'std::__ios_failure'
  what():  basic_ios::clear: iostream error

Program received signal SIGABRT, Aborted.
0x00007ffff7ad8615 in raise () from /usr/lib/libc.so.6

我可以通过抓住它来确认:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream f;
    f.exceptions( std::ifstream::failbit | std::ifstream::badbit );

    try {
        f.open("data/all-patents.dat", std::ifstream::in);
    }
    catch (std::ifstream::failure e) {
        std::cout << "Caught exception opening: " << e.what() << "\n";
    }
    
    std::string l;
    try {
        while (!std::getline(f, l).eof()) {
            // do something
        }
    }
    catch (std::ifstream::failure e) {
        std::cout << "Caught exception reading: " << e.what() << "\n";
    }

}

输出:Caught exception reading: basic_ios::clear: iostream error

尽管我没有在ios::exceptions 的掩码中使用ifstream::eofbit,但为什么EOF 会引发异常?有没有一种方法可以让我继续使用ios::exceptions,而不必将我的while 循环包含在try 中?

【问题讨论】:

  • @TedLyngmo,我的理解是我传递给ios::exceptions 的异常掩码定义了何时应该引发异常,并排除eofbit
  • "异常掩码决定了流在发生时会抛出类型失败异常的错误状态。" - 因此,您可以选择您想要的状态例外。
  • 无关:您的循环可能应该是while (std::getline(f, l))。我不知道你为什么最后有eof()
  • @TedLyngmo,我测试.eof() 以在文件到达EOF 时使while 条件为假,因为getline 返回ifstream 而不是bool
  • ifstream 可以在布尔上下文中使用operator bool 进行测试,就像我展示的那样 - 这与not f.fail()f.fail() 相同,如果badbitfailbit 返回true是真的。对于这样的循环,这通常是您想要的测试。

标签: c++ exception ifstream eof getline


【解决方案1】:

您在failbit 上启用引发异常,稍后当std::getline(f, l) 无法提取任何字符时,它将设置触发异常的failbit

【讨论】:

  • 事实证明,eofbitfailbit 都命中了 EOF 集。我不知道。
  • @scozy 设置失败位的不是 EOF。击中 EOF 仅设置 eofbit。它无法提取设置failbit任何 个字符。您可以点击 EOF 并获取 eofbit 设置 提取字符。在这种情况下,failbit 将不会被设置。
猜你喜欢
  • 1970-01-01
  • 2014-10-02
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 2012-04-01
  • 2020-04-20
  • 1970-01-01
相关资源
最近更新 更多