while(istream) iterates one too many times

I'm trying to use a while loop to read each line in an istream. The loop body is executed one more time after reaching the last line in the stream. How can I fix this?

1
2
3
4
	while(input)
	{
	    ...
	}
Last edited on
while(std::getline(input, string))

or

while(input >> string)

All assuming "input" is a stream you've made.
Hello MattJ812,

Of course it is. It would help if you provided more of the code in the while loop unless the function call, I guess that is what it is even though the ; is missing.

Something to explain it better:
1
2
3
4
5
while (input)
{
	input >> aString;
	std::cout << "\n " << aString << '\n';
}

This works the same as if you had used "!input.eof()" both do not work the way that you are expecting. When you first do your check in the while condition the good bit is set to 1 and all the others are set to (0) zero.

So you enter the loop and read the next to last line of the file and print out "next to last line". Going back to your while condition the good bit is still 1, so you enter the loop and read the last line of your file print out "last line". Returning to the while condition the good bit is still 1, so you enter the loop and try to read past end of file setting the "eof" bit to 1 and the good bit to (0) zero. But you still have the cout statement to process and because there was nothing to read you print out "last line" a second time because that is what was left in the variable to use.

By the time the while condition figures out you are at end of file you have processed what is in the while loop one extra time using whatever was in the variable(s).

A way to use what you have is:
1
2
3
4
5
6
7
8
input >> aString;

while (input)
{
	std::cout << "\n " << aString << '\n';

	input >> aString;
}

Doing the read last will catch the end of file when it happens. Of course you have to do your first read before the while loop for this to work.

The better code for reading a file of unknown length is:
1
2
3
4
while (input >> aString)
{
	std::cout << "\n " << aString << '\n';
}

When the condition tries to read past end of file the stream will fail and so will the while condition.

Hope that helps,

Andy
Topic archived. No new replies allowed.