ifstream eof not reporting eof?

Discussion in 'C++' started by SpreadTooThin, Jun 13, 2007.

  1. I just did a loop

    ifstream i(myfile, ios::binary);

    while (!i.eof())
    i.read(buff, 2);

    Well it should have come out of the loop but it tried to do the read
    operation again...
    Now... I know I should have checked the return of the read, but read
    returns an ifstream...
    How do I go about checking that the data was actually read and what
    the heck is wrong with eof?
    SpreadTooThin, Jun 13, 2007
    1. Advertisements

  2. Reading the fine manual... It seems that eof will only be true after
    you have tried to read and failed...
    Pardon me but isn't that a bit silly?
    SpreadTooThin, Jun 13, 2007
    1. Advertisements

  3. So? 'ifstream' has 'good()' member, and it has conversion to 'void*',
    so you can do

    while (i.read(buff, 2))


    while (i.read(buff, 2).good())
    Nothing the heck is wrong with eof. You probably don't understand
    how to use it. Try RTFM. Pay specific attention to what flags are
    set when 'read' succeeds and/or when it fails, or when it reads less
    than requested. Then perform proper actions depending on the flags
    you see set after calling 'read'. Also, get a decent book that has
    unformatted I/O explained.

    Victor Bazarov, Jun 13, 2007
  4. SpreadTooThin

    Gavin Deane Guest

    Nothing is wrong with eof as long as you use it in the right way -
    which you aren't. Change your code to use eof as described in the FAQ
    and see if that fixes your problem.

    Gavin Deane
    Gavin Deane, Jun 13, 2007
  5. No. Why is it silly? 'eof' is an error condition that indicates some
    specific state of the stream. The 'end-of-file' is not reached upon
    a successful read operation. If it's successful, there is no error,

    Victor Bazarov, Jun 13, 2007
  6. SpreadTooThin

    Gavin Deane Guest

    Well done. That's the key.
    Uh.... no, not really. See FAQ 15.5.

    Gavin Deane
    Gavin Deane, Jun 13, 2007
  7. SpreadTooThin

    Ron Natalie Guest

    SpreadTooThin wrote:
    Nope, that is the way a large plethora of underlying I/O systems
    work. EOF isn't detectable unless you try to read something.
    C++ takes this as a common denominator.
    Ron Natalie, Jun 14, 2007
  8. SpreadTooThin

    BobR Guest

    Well, you can 'detect' it:

    if( MyInFile.peek() == EOF ){/*....*/}

    ....but the 'peek()' is still a 'read', and that line is seldom usable.
    BobR, Jun 14, 2007
  9. SpreadTooThin

    James Kanze Guest

    And how do you propose to implement anything else, given the
    constraint of also supporting interactive devices, and input of
    various types? Suppose the data left in the file is " \n".
    What should i.eof() return in the following code:

    if ( ! i.eof() ) {
    if ( rand() % 1 == 0 ) {
    char ch = i.get() ; // guaranteed, since ! i.eof()
    } else {
    int i ;
    i >> ch ; // guaranteed, since ! i.eof()
    James Kanze, Jun 15, 2007
  10. SpreadTooThin

    James Kanze Guest

    No, no, no, no. There is *never* any time that ios::good()
    should be used, since it returns false if eofbit is set (and so
    may return false when the read actually succeeds).
    Nothing that it would be possible to fix, you mean. A
    predictive EOF would in fact be very nice. In the distant past,
    some languages (e.g. Pascal) have tried to specify it. In the
    end, it never worked correctly; it's nice, but no one knows how
    to specify it so that it is both useful and implementable.
    And pay specific attention to what flags are tested by each
    function as well:). The basic philosophy of not supporting
    predictive EOF is quite justifiable, given the experience of
    other languages. The choice and naming of the functions in ios
    a lot less so.
    James Kanze, Jun 15, 2007
  11. SpreadTooThin

    James Kanze Guest

    The case of binary input, as in his code, is a bit more awkward,
    since there are two possible definitions of success: he read 2
    bytes, or he read some bytes. The standard takes the first
    definition: if i.read(buff,2) succeeds, (i.e. if
    "i.read(buff,2)" is treated as true in an if or a while), then 2
    bytes have actually been read, no more, no less. If you're
    interested in partial reads, you have to do something like:

    while ( i.read( buff, 2 ) || i.gcount() != 0 ) {
    // ...

    Note that this is only true for binary reads of (potentially)
    more than one byte. In all other cases, the standard idiom
    explained in the FAQ is good.
    James Kanze, Jun 15, 2007
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.