Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::getline throwing when it hits eof

std::getline throws exception when it gets an eof. this is how I am doing.

std::ifstream stream;
stream.exceptions(std::ifstream::failbit|std::ifstream::badbit);
try{
  stream.open(_file.c_str(), std::ios_base::in);
}catch(std::ifstream::failure e){
  std::cout << "Failed to open file " << _file.c_str() << " for reading" << std::endl;
}
while(!stream.eof()){
  std::string buffer = "";
  std::getline(stream, buffer);
  //process buffer
  //I do also need to maintain state while parsing
}

In the above code getline is throwing exception as it gets eof How to handle this situation ?

EDIT

std::string buffer = "";
while(std::getline(stream, buffer)){
    //also causes getline to hit eof and throw
}
like image 257
Dipro Sen Avatar asked Aug 04 '12 10:08

Dipro Sen


People also ask

Does Getline return EOF?

On success, getline() and getdelim() return the number of characters read, including the delimiter character, but not including the terminating null byte ('\0'). This value can be used to handle embedded null bytes in the line read. Both functions return -1 on failure to read a line (including end-of-file condition).

Does Getline go to the next line?

getline(cin, newString); begins immediately reading and collecting characters into newString and continues until a newline character is encountered. The newline character is read but not stored in newString.

What is the default delimiter for Getline?

We can also use the delim argument to make the getline function split the input in terms of a delimiter character. By default, the delimiter is \n (newline).


1 Answers

As you said, calling getline when the stream is currently positioned on the blank line at the end of the file will set both eofbit (because it reaches the end of file) and failbit (because nothing could be extracted, not even the line delimiter).

So, if you have set the stream to throw exceptions when failbit is set, you get an exception thrown when reading that blank line.

To prevent that, you can peek for the next character on the stream before calling getline:

std::string buffer = "";
while(stream.peek() != EOF && std::getline(stream, buffer)){
    //do something with the buffer
}
like image 73
Sebastien Gehant Avatar answered Oct 05 '22 08:10

Sebastien Gehant