views:

69

answers:

3

I was looking at this article on Cplusplus.com, http://www.cplusplus.com/reference/iostream/istream/peek/

I'm still not sure what peek() returns if it reaches the end of the file.

In my code, a part of the program is supposed to run as long as this statement is true

(sourcefile.peek() != EOF)

where sourcefile is my ifstream.

However, it never stops looping, even though it has reached the end of the file.

Does EOF not mean "End of File"? Or was I using it wrong?

+2  A: 

EOF is for the older C-style functions. You should use istream::traits_type::eof().

Edit: viewing the comments convinces me that istream::traits_type::eof() is guaranteed to return the same value as EOF, unless by chance EOF has been redefined in the context of your source block. While the advice is still OK, this is not the answer to the question as posted.

Mark Ransom
that's strange, I tried that and it still goes on forever
jwaffe
`::eof()` returns `EOF` for `char_traits<char>`, which is the one of `istream`.
Johannes Schaub - litb
Even though T.E.D helped me a lot, Mark answered the question at the top of the page, so I'm choosing him as the accepted answer. Thanks for your help guys!
jwaffe
@jwaffe please note that he did not answer your question. His attempt at solving your problem failed because `EOF` is always equal to `istream::traits_type::eof()`. This is an instance of http://meta.stackoverflow.com/questions/64308/try-xyz-answers . (I'm a retard, but I'm ok with that).
Johannes Schaub - litb
@Johannes, is it a requirement that eof() return EOF, or is it just a common convention?
Mark Ransom
@jwaffe, you are not required to select an answer, especially if none of the answers actually solved your problem. It might not be too late to unclick my answer, because I'm convinced that it didn't really help.
Mark Ransom
The Standard says "The member eof() returns EOF" (for the `char` version) and "The member eof() returns WEOF" (for the `wchar_t` version).
Johannes Schaub - litb
In Mark's defense (I'm actually his one upvote), I could easily see where, due to unfortunate `#include`'s or something, `EOF` could have ended up `#define`'d to something else. That's what my first bullet was getting at. So his advice is good IMHO.
T.E.D.
@T.E.D. sure I think it's good to advice to use `eof()`, I do agree. But really the answer reads to me as "This fails because you use EOF. You need to use istream::traits_type::eof() which has the correct value"
Johannes Schaub - litb
So EOF is synonymous with istream::traits_type::eof()?
jwaffe
+2  A: 

Things that come to mind (without seeing your code).

  • EOF could be defined differently than you expect
  • sourcefile.peek() doesn't advance the file pointer. Are you advancing it manually somehow, or are you perhaps constantly looking at the same character?
T.E.D.
I found the problem, it actually didn't have anything to do with my while loop, the very last read was looking for '/n', but it didn't find it because it was actually the end of the file. I should have put something in there to stop it in case it was the end of the file.
jwaffe
+1  A: 

Consulting the Standard,

Returns:traits::eof() ifgood()isfalse. Otherwise,returnsrdbuf()->sgetc().

As for sgetc(),

Returns: If the input sequence read position is not available, returns underflow().

And underflow,

If the pending sequence is null then the function returns traits::eof() to indicate failure.

So yep, returns EOF on end of file.

An easier way to tell is that it returns int_type. Since the values of int_type are just those of char_type plus EOF, it would probably return char_type if EOF weren't possible.

As others mentioned, peek doesn't advance the file position. It's generally easiest and best to just loop on while ( input_stream ) and let failure to obtain additional input kill the parsing process.

Potatoswatter