fgetc and EOF

This is a discussion on fgetc and EOF within the C Programming forums, part of the General Programming Boards category; Code: FILE *fp; int c; if ((fp = fopen (oldname, "rb")) == NULL) return -1; while ((c = fgetc(fp)) != ...

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    11

    fgetc and EOF

    Code:
    FILE *fp;
    int c;
    
    if ((fp = fopen (oldname, "rb")) == NULL)
        return -1;
    
    while ((c = fgetc(fp)) != EOF)
        fprintf(stdout, "%c", c);
    
    fclose(fp);
    This is a "BUGBUSTER" from the book "teach yourself C in 21 days". The question is: Is there anything worng with this code. My opinion: NO. But the book says this:

    "You can't use the EOF check with a binary file. You should use the feof() function". As i read on the forum here, you must not use feof at all!!.

    But when i look in the K&R "bible" it says this:
    "fgetc returns the next charakter of stream as an unsigned char (converted to an int), or EOF if end of file or error occurs"

    It says it return EOF when the file ends, so the above code is ok i think.

    Can some experts give their opinion ?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,310
    I am not an expert, but I think that you are correct. EOF must have a negative value, so there can be no conflict with the normal return value of fgetc().

    Incidentally, it is not so must that you must not use feof() at all, but that you should not use it to control a loop.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,417
    Your code is fine.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >"You can't use the EOF check with a binary file. You should use the feof() function"
    Your book is full of it. This answer strikes me as a fundamental misunderstanding about how C handles stream conditions. And if a book can get something simple like that wrong, I shudder to imagine what else it gets wrong.

    >As i read on the forum here, you must not use feof at all!!
    Aroo? Of course you should use feof, but only when it's appropriate.

    Here's the reality. fgetc will return EOF in the following three conditions:

    1) The end-of-file indicator was set prior to the call.
    2) The end-of-file indicator is set by fgetc during the call.
    3) A read error occurs.

    The last condition sets the error indicator. That's how fgetc works in all cases; the orientation of the stream is irrelevant, so whatever your book says about the EOF return value not working with binary streams for some reason, it's wrong. If you need specific details about what happened, as opposed to just a global "oh, it didn't work", then feof and ferror enter the picture:
    Code:
    int ch;
    
    while ( ( ch = fgetc ( in ) ) != EOF )
      process ( ch );
    
    if ( feof ( in ) )
      puts ( "end-of-file reached" );
    
    if ( ferror ( in ) )
      puts ( "a read error occurred" );
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Jul 2008
    Posts
    11
    Thx, for clearing thing guys, great forum!. Im going to read multiple books!, to get a better understanding. ( and of course read posts here ).

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by laserlight View Post
    EOF must have a negative value, so there can be no conflict with the normal return value of fgetc().
    EOF could have been greater than zero if the maximum value of an int was greater than the maximum value of a char, and the standard didn't specifically disallow it, I think.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,310
    EOF could have been greater than zero if the maximum value of an int was greater than the maximum value of a char, and the standard didn't specifically disallow it, I think.
    I do not get your reasoning. It is quite clear that EOF is returned as an int, so it does not matter what is the choice of value of EOF, so long as it is negative and fits into an int.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Consider that char ranges from 0-255. int ranges from -32767-32767. Barring the specific prohibition of EOF being positive int the standard (which is there, I admit), EOF could have been positive, in the range from 256-32767, inclusive. So the reason it can't be positive in the standard is not because it would conflict with a char value, but perhaps some other reason. You seemed to say otherwise, and that's what I'm objecting about, not that it can be positive in a conforming implementation, but rather that that is not the reason it can't be allowed, AFAIK.
    Last edited by robwhit; 08-28-2008 at 01:37 PM.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >and the standard didn't specifically disallow it
    The standard does specifically disallow it by requiring that EOF be a negative quantity.
    My best code is written with the delete key.

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Yes, I know... but why?

  11. #11
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    Probably because it's easier and cleaner to prohibit non-negative EOF than it is to define a non-negative EOF such that it works with any combination of the allowable ranges for unsigned char and int.
    My best code is written with the delete key.

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    But it wouldn't have to work on any combination, just the combination in use by the implementation at that time.

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >But it wouldn't have to work on any combination
    So you're suggesting that a viable option was to throw portability out the window for a more complicated definition of EOF with no added benefit? I'm glad you aren't on the standards committee.
    My best code is written with the delete key.

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    I think portability doesn't enter the equation since its value is implementation-specific anyway. And I think it would be a less complicated definition, because there would be one less restriction, namely, the one about EOF having to be negative.

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    Well, the point is moot anyway because neither of us have any say in the matter.
    My best code is written with the delete key.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fgetc - Extra newline
    By Koiby25 in forum C Programming
    Replies: 5
    Last Post: 02-22-2009, 03:45 PM
  2. help with fgetc
    By agentsmith in forum C Programming
    Replies: 3
    Last Post: 04-15-2008, 10:08 AM
  3. character input using fgetc() code???
    By lesrhac03 in forum C Programming
    Replies: 3
    Last Post: 03-27-2008, 10:55 PM
  4. fgetc - returns immediately?
    By sean in forum C Programming
    Replies: 2
    Last Post: 12-11-2004, 09:24 AM
  5. fgetc() and getc()
    By The Dog in forum C Programming
    Replies: 2
    Last Post: 07-24-2002, 05:00 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21