scozy
scozy

Reputation: 2582

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

I am trying to use an ifstream that I need to be able to loop through using getline but would like to have throw exceptions using 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
    }

}

But when getline hits EOF, it throws an exception:

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

Which I can confirm by catching it:

#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";
    }

}

Output: Caught exception reading: basic_ios::clear: iostream error

Why does EOF throw an exception despite me not using ifstream::eofbit in ios::exceptions's mask? Is there a way I can keep using ios::exceptions without having to enclose my while loop in a try?

Upvotes: 1

Views: 345

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

You turn on throwing exceptions on failbit and later when std::getline(f, l) fails to extract any characters it will set failbit which is triggering the exception.

Upvotes: 1

Related Questions