std::getline throwing when it hits eof

a 夏天 提交于 2020-01-21 04:48:47

问题


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
}

回答1:


You activate the exception handling of your stream at the very beginning of your code:

stream.exceptions(std::ifstream::failbit|std::ifstream::badbit);

Now if the extraction of formatted data such as floating-point values, integers or strings will fail, it will set the failbit:

eofbit    indicates that an input operation reached the end of an 
          input sequence;
failbit   indicates that an input operation failed to read the expected 
          characters, or that an output operation failed to generate the 
          desired characters.

While getline(stream,buffer) will indeed set the eofbit if it reaches the end of a file, it will also set the failbit, since the desired characters (a line) couldn't be extracted.

Either wrap another try-catch-block around your loop or disable the failbit exception.

Example:

#include <iostream>
#include <fstream>

int main(){
  std::ifstream stream("so.cc");
  stream.exceptions(std::ifstream::failbit|std::ifstream::badbit);
  std::string str;

  try{
    while(std::getline(stream, str));
  }catch(std::ifstream::failure e){
    std::cerr << "Exception happened: " << e.what() << "\n"
      << "Error bits are: "
      << "\nfailbit: " << stream.fail() 
      << "\neofbit: " << stream.eof()
      << "\nbadbit: " << stream.bad() << std::endl;    
  }
  return 0;
}

Result:

Exception happened: basic_ios::clear
Error bits are:
failbit: 1
eofbit: 1
badbit: 0

Note that both eofbit and failbit are set.

See also:

  • std::ios_base::iostate
  • Table 124 in § 27.5.3.1.5 (see above)


来源:https://stackoverflow.com/questions/11807804/stdgetline-throwing-when-it-hits-eof

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!