tags:

views:

416

answers:

5

I'm reading in data from a file that has three columns. For example the data will look something like:

3  START  RED
4  END    RED

To read in the data I'm using the following check:

while (iFile.peek() != EOF) {
   // read in column 1
   // read in column 2
   // read in column 3
}

My problem is that the loop usually does on extra loop. I'm pretty sure this is because a lot of text editors seem to but a blank line after the last line of actual content.

I did a little bit of Googling and search on SO and found some similar situations such as http://stackoverflow.com/questions/21647/c-reading-from-text-file-until-eof-repeats-last-line however I couldn't quite seem to adapt the solution given to solve my problem. Any suggestions?

A: 

If any of the reads fail (where you read the column data), just break out of the while loop. Presumably you are then at the end of the file and reading the last 'not correct' line

Toad
How would I go about checking whether a read failed? Just by checking to see if the value read in is an accept value? If so I don't this will work because when it fails to read in new data it just leaves the old data in the variable. Is there some other way of checking for this?
blcArmadillo
the EOF will be set. But just like the others said: it might be easier to just go line by line, and parse the values out of the line, instead of doing 3 consecutive reads
Toad
A: 

Maybe you'll consider it a good idea to handle whitespace and other invalid input then. Perhaps some basic validation of columns 1,2,3 would be desirable as well.

Michael Foukarakis
A: 

Don't worry about the number of times that you loop: just validate your data and handle invalid inputs.

Basically, check that you have three columns to read and if you don't decide if it's because the file is over or because of some other issue.

Francesco
+1  A: 

Presuming iFile is an istream:

You should break out of the loop on any error, not only on EOF (which can be checked for with iFile.eof(), BTW), because this is an endless loop when any format failure sets the stream into a bad state other that EOF. It is usually necessary to break out of a reading loop in the middle of the loop, after everything was read (either successfully or not), and before it is entered.

To make sure there isn't anything interesting coming anymore, you could, after the loop, reset the stream state and then try to read whitespace only until your reach EOF:

while( !iFile.eof() )
{
   iFile >> std::ws;
   string line;
   std::getline(iFile,line);
   if(!line.empty()) error(...);
}
sbi
+2  A: 

EOF is not a prediction but an error state. Hence, you can't use it like you're using it now, to predict whether you can read Column 1, 2 and 3. For that reason, a common pattern in C++ is:

while (input >> obj1 >> obj2) {
  use(obj1, obj2);
}

All operator>>(istream& is, T&) return the inputstream, and when used in boolean context the stream is "true" as long as the last extraction succeeded. It's then safe to use the extracted objects.

MSalters