c++file-ioeofistringstream

Extraction Operator reaching EOF on istringstream, behavioral change with int/char/string


So I am doing some simple file I/O in c++ and I notice this behaviour, not sure if I am forgetting something about the extraction operator and chars

Note that the file format in Unix.

ifstream infile("test.txt");
string line;
while(getline(infile, line)){
  istringstream iss(line);
  
  **<type>** a;
  
  for(...){
     iss >> a;
  }

  if(iss.eof()) 
    cout << "FAIL" << endl;

}

Say that the input file test.txt looks like this and the <type> of a is int

$ is the newline character (:set line)

100 100 100$
100 100 100$

what I notice is that after the first line is read, EOF is set true;

If the input file is like so, and the <type> of a is char:

a b c$
a b c$

Then the Code behaves perfectly as expected.

From what I understand about File I/O and the extraction operator, the leading spaces are ignored, and the carriage lands on the character after the input is taken out of the input stringstream iss. So in both cases, at the end of each stringstream the carriage lands on the newline character, and it shouldn't be an EOF.

Changing the <type> of a to string had similar failure as <type> = int

BTW failbit is not set,
at the end: good = 0
fail = 0
eof = 1


Solution

  • getline has extracted and discarded the newline, so line contains 100 100 100, not 100 100 100$, where $ is representing the newline. This means reading all three tokens from the line with a stringstream and the >> operator may reach the EOF and produce the FAIL message.

    iss >> a; when a is an int or a string will skip all preceding whitespace and then continue extracting until it reaches a character that can't possibly be part of an int or is whitespace or is the end of the stream. On the third >> from the stream, the end of the stream stops the extraction and the stream's EOF flag is set.

    iss >> a; when a is an char will skip all preceding whitespace and then extract exactly one character. In this case the third >> will extract the final character and stop before seeing the end of the stream and without setting the EOF flag.