如何使 getline 与 ios::exceptions 兼容?

How to make getline play nice with ios::exceptions?

我正在尝试使用 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 中?

您在 failbit 上打开抛出异常,稍后当 std::getline(f, l) 无法提取任何字符时,它将设置 failbit 触发异常。