akashrajkn akashrajkn - 24 days ago 12
C++ Question

getline() throws basic_ios::clear exception after reading the last line

I am writing a unit test for file read using qtestlib, C++ (clang LLVM version 8.0). I have the following code for reading a file line by line.

std::ifstream infile;

try {
infile.open(path.c_str());
std::ios_base::iostate exceptionMask = infile.exceptions() | std::ios::failbit;
infile.exceptions(exceptionMask);

} catch (std::ios_base::failure& e) {
// print the exception
qDebug() << "Exception caught: " << QString::fromStdString(e.what());
}

try {
std::string line;
while (std::getline(infile, line)) {
// print the line
qDebug() << QString::fromStdString(line);
}

} catch (std::ios_base::failure& e) {
qDebug() << "Exception caught: " << QString::fromStdString(e.what());
}


The issue:

The above code reads all the lines in the file and prints it. But after printing the last line, it throws an exception and prints the following,


Exception caught: "basic_ios::clear"


I followed many threads, but could not find the solution to this. Why am I getting this error?

Answer

After you have read and printed all the lines, the while (std::getline(infile, line)) will still try to read another line. If it fails totally - zero characters read - it sets failbit to signal its failure.

The odd part of the error message is that, despite its name, basic_ios::clear can be used to set the failure bit and will also throw an exception if you have enabled the same bit with exceptions.