a problem when using int feof(FILE *fp);

Discussion in 'C Programming' started by kindrain, Jul 12, 2008.

  1. kindrain

    kindrain Guest

    the code checks whether a.txt has exact the same lines, then write
    different lines into b.txt

    Here it is:
    (before that ,you should creat a.txt)
    ----------------------
    #include<stdio.h>
    #include<string.h>
    void main(){
    FILE *fp,*ftemp;
    char ch[50],comp[50];
    int lflag;

    fp=fopen("a.txt","r");
    ftemp=fopen("b.txt","w+");

    /*the following checks whether fp has exact the same lines, then write
    different lines into ftemp*/
    while(!feof(fp)){
    fgets(ch,50,fp);
    lflag=1;
    rewind(ftemp); /*the file point points to the beginning of ftemp*/
    while(!feof(ftemp)){
    fgets(comp,50,ftemp);
    if(!strcmp(ch,comp)){
    lflag=0;
    break;
    }
    } /*check all lines in ftemp. if there is a string equals to ch,then
    make lflag=0;*/
    if(lflag){ fseek(ftemp,0,2);
    fputs(ch,ftemp);
    puts(ch);
    } /*if lflag==1,then write string ch into ftemp, and output to the
    screen.*/
    }

    fclose(fp);
    fclose(ftemp);
    }
    ------------------------

    when a.txt has some chars, we get the right result;
    but when a.txt is empty, we can see the following words both in b.txt
    and in the screen:
    ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌP»B


    now here comes a question:
    if fp points to an empty file,then "feof(fp)" should be equal to
    1,then how can it step into while?

    I've thought it for several days.so--

    Does every file has an EOF in the end?(I find empty files are 0k)
    Does the file point points to the first char when the file is opened?
    Are the first char and last char both EOF in an empty file?


    Hoping for your help!
     
    kindrain, Jul 12, 2008
    #1
    1. Advertising

  2. kindrain

    santosh Guest

    kindrain wrote:

    > the code checks whether a.txt has exact the same lines, then write
    > different lines into b.txt
    >
    > Here it is:
    > (before that ,you should creat a.txt)
    > ----------------------
    > #include<stdio.h>
    > #include<string.h>
    > void main(){


    This is not portable. Use int main(void) and return either 0 or
    EXIT_FAILURE from main. For EXIT_FAILURE you need stdlib.h.

    > FILE *fp,*ftemp;
    > char ch[50],comp[50];
    > int lflag;
    >
    > fp=fopen("a.txt","r");
    > ftemp=fopen("b.txt","w+");
    >
    > /*the following checks whether fp has exact the same lines, then write
    > different lines into ftemp*/
    > while(!feof(fp)){


    This is apparently a common beginner error. In C the function feof and
    ferror should *not* be called *before* an I/O function (like
    fgetc/fgets etc) has tried to read a stream.

    Rather call your I/O function and *if* that function indicates that it
    has failed (by returning EOF or NULL or as documented), *then* you can
    call feof or ferror to *disambiguate* between whether the failure was
    due to end-of-file condition or due to a read error.

    > fgets(ch,50,fp);
    > lflag=1;
    > rewind(ftemp); /*the file point points to the beginning of ftemp*/
    > while(!feof(ftemp)){


    Ditto.

    > fgets(comp,50,ftemp);
    > if(!strcmp(ch,comp)){
    > lflag=0;
    > break;
    > }
    > } /*check all lines in ftemp. if there is a string equals to ch,then
    > make lflag=0;*/
    > if(lflag){ fseek(ftemp,0,2);
    > fputs(ch,ftemp);
    > puts(ch);
    > } /*if lflag==1,then write string ch into ftemp, and output to the
    > screen.*/
    > }
    >
    > fclose(fp);
    > fclose(ftemp);
    > }
    > ------------------------
    >
    > when a.txt has some chars, we get the right result;
    > but when a.txt is empty, we can see the following words both in b.txt
    > and in the screen:
    > ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌP»B
    >
    >
    > now here comes a question:
    > if fp points to an empty file,then "feof(fp)" should be equal to
    > 1,then how can it step into while?


    This proceeds from your misconception that one must check with feof
    before reading. In C it is the other way around. First try to read and
    if the read function indicates failure then check with feof if it is
    because of end-of-file or check with ferror if it was due to a read
    error.

    > I've thought it for several days.so--


    If you had read the documentation for feof or ferror or any elementary C
    textbook like K&R2 then you needn't have wasted days on this.

    > Does every file has an EOF in the end?(I find empty files are 0k)


    EOF is a macro which resolves to a negative int value. It is returned by
    many of C's I/O function to indicate *any* type of failure. A return
    value of EOF does *not* mean that end-of-file has been encountered.
    Only if feof returns true does it mean so.

    > Does the file point points to the first char when the file is opened?


    If it has not been opened in append mode then yes.

    > Are the first char and last char both EOF in an empty file?


    A read from an empty file will return EOF. Further testing with feof
    will return true. What the file actually contains is implementation
    defined.

    > Hoping for your help!
     
    santosh, Jul 12, 2008
    #2
    1. Advertising

  3. kindrain

    kindrain Guest

    On Jul 12, 4:44 pm, santosh <> wrote:
    > kindrain wrote:
    > > the code checks whether a.txt has exact the same lines, then write
    > > different lines into b.txt

    >
    > > Here it is:
    > > (before that ,you should creat a.txt)
    > > ----------------------
    > > #include<stdio.h>
    > > #include<string.h>
    > > void main(){

    >
    > This is not portable. Use int main(void) and return either 0 or
    > EXIT_FAILURE from main. For EXIT_FAILURE you need stdlib.h.
    >
    > > FILE *fp,*ftemp;
    > > char ch[50],comp[50];
    > > int lflag;

    >
    > > fp=fopen("a.txt","r");
    > > ftemp=fopen("b.txt","w+");

    >
    > > /*the following checks whether fp has exact the same lines, then write
    > > different lines into ftemp*/
    > > while(!feof(fp)){

    >
    > This is apparently a common beginner error. In C the function feof and
    > ferror should *not* be called *before* an I/O function (like
    > fgetc/fgets etc) has tried to read a stream.
    >
    > Rather call your I/O function and *if* that function indicates that it
    > has failed (by returning EOF or NULL or as documented), *then* you can
    > call feof or ferror to *disambiguate* between whether the failure was
    > due to end-of-file condition or due to a read error.
    >
    > > fgets(ch,50,fp);
    > > lflag=1;
    > > rewind(ftemp); /*the file point points to the beginning of ftemp*/
    > > while(!feof(ftemp)){

    >
    > Ditto.
    >
    >
    >
    >
    >
    > > fgets(comp,50,ftemp);
    > > if(!strcmp(ch,comp)){
    > > lflag=0;
    > > break;
    > > }
    > > } /*check all lines in ftemp. if there is a string equals to ch,then
    > > make lflag=0;*/
    > > if(lflag){ fseek(ftemp,0,2);
    > > fputs(ch,ftemp);
    > > puts(ch);
    > > } /*if lflag==1,then write string ch into ftemp, and output to the
    > > screen.*/
    > > }

    >
    > > fclose(fp);
    > > fclose(ftemp);
    > > }
    > > ------------------------

    >
    > > when a.txt has some chars, we get the right result;
    > > but when a.txt is empty, we can see the following words both in b.txt
    > > and in the screen:
    > > ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌP»B

    >
    > > now here comes a question:
    > > if fp points to an empty file,then "feof(fp)" should be equal to
    > > 1,then how can it step into while?

    >
    > This proceeds from your misconception that one must check with feof
    > before reading. In C it is the other way around. First try to read and
    > if the read function indicates failure then check with feof if it is
    > because of end-of-file or check with ferror if it was due to a read
    > error.
    >
    > > I've thought it for several days.so--

    >
    > If you had read the documentation for feof or ferror or any elementary C
    > textbook like K&R2 then you needn't have wasted days on this.
    >
    > > Does every file has an EOF in the end?(I find empty files are 0k)

    >
    > EOF is a macro which resolves to a negative int value. It is returned by
    > many of C's I/O function to indicate *any* type of failure. A return
    > value of EOF does *not* mean that end-of-file has been encountered.
    > Only if feof returns true does it mean so.
    >
    > > Does the file point points to the first char when the file is opened?

    >
    > If it has not been opened in append mode then yes.
    >
    > > Are the first char and last char both EOF in an empty file?

    >
    > A read from an empty file will return EOF. Further testing with feof
    > will return true. What the file actually contains is implementation
    > defined.
    >
    >
    >
    > > Hoping for your help!- Hide quoted text -

    >
    > - Show quoted text -- Hide quoted text -
    >
    > - Show quoted text -





    so no EOF in files?
    but how does feof work? does it first read a char,then return true if
    it fails,else return zero?
     
    kindrain, Jul 12, 2008
    #3
  4. kindrain

    santosh Guest

    kindrain wrote:

    <snip>

    > so no EOF in files?


    As I said EOF is a macro defined in stdio.h that evaluates to a negative
    value of type int that is returned by several of C's standard I/O
    functions to signal *either* end-of-file *or* some other error. Which
    one of these is the case for a particular failed call is determined by
    testing with feof or ferror *after* the call.

    > but how does feof work?


    The Standard doesn't precisely spell out how feof (or ferror) actually
    works. That is upto the implementations. Conceptually feof and ferror
    will test the end-of-file and error indicators for the stream
    respectively and return true when they are set or false otherwise.

    These "indicators" would've been set (or cleared) by the previous I/O
    function called on the stream.

    <snip>
     
    santosh, Jul 12, 2008
    #4
  5. kindrain <> writes:

    > On Jul 12, 4:44 pm, santosh <> wrote:

    <lots, but not commented on, so I've trimmed it>

    What is the point of quoting everything if you are going to summarise
    at the end?

    > so no EOF in files?


    Santosh did not say that. If you had interleaved your reply with his
    I would have some idea what part of his detailed reply led you to
    conclude this. EOF is a macro. It can't be "in files". A read
    operation can fail because there is no more data (and many C function
    return the value of the EOF macro when the fail). After that has
    happened, feof will return true.

    > but how does feof work?


    Do you really mean what is its specification? If so, you must get a
    book (or online reference) that tells you. You can't lean C by
    guessing what functions do and posting questions when things don't
    work. All good books will tell you what feof is for and how to use
    it. Asking how a system function /works/ rarely helps (for example
    feof is usually trivial -- returning the value of a bit from a set of
    status flags).

    > does it first read a char,then return true if
    > it fails,else return zero?


    No, it just reports the end-of-file indicator for the given stream.

    --
    Ben.
     
    Ben Bacarisse, Jul 12, 2008
    #5
  6. kindrain

    kindrain Guest

    On Jul 12, 5:49 pm, santosh <> wrote:
    > <snip>


    thank you for your sharing of time.
     
    kindrain, Jul 12, 2008
    #6
  7. kindrain

    kindrain Guest

    On Jul 12, 5:58 pm, Ben Bacarisse <> wrote:
    <snip>

    sorry I don't know the rule here clearly.

    and thank you too.
     
    kindrain, Jul 12, 2008
    #7
  8. kindrain

    Ali Karaali Guest

    On 12 Temmuz, 11:44, santosh <> wrote:

    > > /*the following checks whether fp has exact the same lines, then write
    > > different lines into ftemp*/
    > > while(!feof(fp)){

    >
    > This is apparently a common beginner error. In C the function feof and
    > ferror should *not* be called *before* an I/O function (like
    > fgetc/fgets etc) has tried to read a stream.
    >
    > Rather call your I/O function and *if* that function indicates that it
    > has failed (by returning EOF or NULL or as documented), *then* you can
    > call feof or ferror to *disambiguate* between whether the failure was
    > due to end-of-file condition or due to a read error.


    Can you show me source for this?
     
    Ali Karaali, Jul 12, 2008
    #8
  9. kindrain

    viza Guest

    On Sat, 12 Jul 2008 02:29:26 -0700, kindrain wrote:

    > On Jul 12, 4:44 pm, santosh <> wrote:


    >> This is apparently a common beginner error. In C the function feof and
    >> ferror should *not* be called *before* an I/O function (like
    >> fgetc/fgets etc) has tried to read a stream.
    >>
    >> Rather call your I/O function and *if* that function indicates that it
    >> has failed (by returning EOF or NULL or as documented), *then* you can
    >> call feof or ferror to *disambiguate* between whether the failure was
    >> due to end-of-file condition or due to a read error.

    >
    > so no EOF in files?
    > but how does feof work? does it first read a char,then return true if
    > it fails,else return zero?


    You try replacing feof() with the following. It allows you to test
    whether a read that you are /about/ to do will be at the end of the file,
    rather than test if the last one you already /did/ was.


    /* at_eof.c by PUBLIC DOMAIN 2005 */

    #include <stdio.h>

    int at_eof(FILE *stream){
    int c;

    if(feof(stream))
    return 1;

    c=fgetc(stream);
    if(EOF==c)
    return 1;

    if(EOF==ungetc(c, stream))
    return -1;

    return 0;
    }
     
    viza, Jul 12, 2008
    #9
  10. Ali Karaali <> wrote:
    > On 12 Temmuz, 11:44, santosh <> wrote:


    > > > /*the following checks whether fp has exact the same lines, then write
    > > > different lines into ftemp*/
    > > > while(!feof(fp)){

    > >
    > > This is apparently a common beginner error. In C the function feof and
    > > ferror should *not* be called *before* an I/O function (like
    > > fgetc/fgets etc) has tried to read a stream.
    > >
    > > Rather call your I/O function and *if* that function indicates that it
    > > has failed (by returning EOF or NULL or as documented), *then* you can
    > > call feof or ferror to *disambiguate* between whether the failure was
    > > due to end-of-file condition or due to a read error.


    > Can you show me source for this?


    #include <stdio.h>
    #include <stdlib.h>

    int main( void )
    {
    FILE *fp;
    int c1,
    char c2;

    if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    {
    fprintf( stderr, "Failed to open file\n" );
    return EXIT_FAILURE;
    }

    /* Read until nothing can be read anymore */

    while ( ( c1 = fgetc( fp ) ) != EOF )
    putchar( c1 );

    #if 0
    /* or, when using fscanf() */

    while ( fscanf( fp, "%c", &c2 ) == 1 )
    putc( c2 )

    /* or, when using fread() */

    while ( fread( &c2, 1, 1, fp ) == 1 )
    putc( c2 )
    #endif

    /* Check why the last read failed */

    if ( feof( fp ) )
    fprintf( stderr, "End of file detected\n" );
    else
    fprintf( stderr, "Read error\n" );

    #if 0
    /* or using ferror() */

    if ( ferror( fp ) )
    fprintf( stderr, "Read error\n" );
    else
    fprintf( stderr, "End of file detected\n" );
    #endif

    close( fp );
    return 0;
    }
    Regards, Jens
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Jul 12, 2008
    #10
  11. kindrain

    santosh Guest

    Ali Karaali wrote:

    > On 12 Temmuz, 11:44, santosh <> wrote:
    >
    >> > /*the following checks whether fp has exact the same lines, then
    >> > write different lines into ftemp*/
    >> > while(!feof(fp)){

    >>
    >> This is apparently a common beginner error. In C the function feof
    >> and ferror should *not* be called *before* an I/O function (like
    >> fgetc/fgets etc) has tried to read a stream.
    >>
    >> Rather call your I/O function and *if* that function indicates that
    >> it has failed (by returning EOF or NULL or as documented), *then* you
    >> can call feof or ferror to *disambiguate* between whether the failure
    >> was due to end-of-file condition or due to a read error.

    >
    > Can you show me source for this?


    Not any specific clauses from the Standard sorry. However when a stream
    is created one would expect it's end-of-file and error indicator to be
    initially cleared. Thereafter each I/O operation on the stream would
    set or clear these indicators as appropriate. They are not updated
    automatically (i.e., in the absence of any I/O operation) as one might
    expect. Rather they indicate the status of the last I/O operation
    (except when they have been explicitly cleared). So it seems more
    natural, IMHO, to test a stream with feof and ferror after an I/O
    request than before, though in some cases both methods will work.
     
    santosh, Jul 12, 2008
    #11
  12. kindrain

    santosh Guest

    viza wrote:

    > On Sat, 12 Jul 2008 02:29:26 -0700, kindrain wrote:
    >
    >> On Jul 12, 4:44 pm, santosh <> wrote:

    >
    >>> This is apparently a common beginner error. In C the function feof
    >>> and ferror should *not* be called *before* an I/O function (like
    >>> fgetc/fgets etc) has tried to read a stream.
    >>>
    >>> Rather call your I/O function and *if* that function indicates that
    >>> it has failed (by returning EOF or NULL or as documented), *then*
    >>> you can call feof or ferror to *disambiguate* between whether the
    >>> failure was due to end-of-file condition or due to a read error.

    >>
    >> so no EOF in files?
    >> but how does feof work? does it first read a char,then return true
    >> if it fails,else return zero?

    >
    > You try replacing feof() with the following. It allows you to test
    > whether a read that you are /about/ to do will be at the end of the
    > file, rather than test if the last one you already /did/ was.
    >
    >
    > /* at_eof.c by PUBLIC DOMAIN 2005 */
    >
    > #include <stdio.h>
    >
    > int at_eof(FILE *stream){
    > int c;
    >
    > if(feof(stream))
    > return 1;


    This is the same as just calling feof.

    > c=fgetc(stream);
    > if(EOF==c)
    > return 1;


    Fgetc could've failed due to a read error.

    > if(EOF==ungetc(c, stream))
    > return -1;
    >
    > return 0;
    > }


    IMHO, this is just over-complicating matters. YMMV.
     
    santosh, Jul 12, 2008
    #12
  13. kindrain

    Guest

    On Jul 12, 1:31 pm, kindrain <> wrote:
    > On Jul 12, 5:58 pm, Ben Bacarisse <> wrote:
    > <snip>
    >
    > sorry I don't know the rule here clearly.
    >
    > and thank you too.


    Don't snip like that, which rule? (you don't need to answer, *I* can
    see the message you replied to)
     
    , Jul 12, 2008
    #13
  14. kindrain

    Chad Guest

    On Jul 12, 4:24 am, (Jens Thoms Toerring) wrote:
    > Ali Karaali <> wrote:
    > > On 12 Temmuz, 11:44, santosh <> wrote:
    > > > > /*the following checks whether fp has exact the same lines, then write
    > > > > different lines into ftemp*/
    > > > > while(!feof(fp)){

    >
    > > > This is apparently a common beginner error. In C the function feof and
    > > > ferror should *not* be called *before* an I/O function (like
    > > > fgetc/fgets etc) has tried to read a stream.

    >
    > > > Rather call your I/O function and *if* that function indicates that it
    > > > has failed (by returning EOF or NULL or as documented), *then* you can
    > > > call feof or ferror to *disambiguate* between whether the failure was
    > > > due to end-of-file condition or due to a read error.

    > > Can you show me source for this?

    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int main( void )
    > {
    > FILE *fp;
    > int c1,
    > char c2;
    >
    > if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    > {
    > fprintf( stderr, "Failed to open file\n" );
    > return EXIT_FAILURE;
    > }
    >
    > /* Read until nothing can be read anymore */
    >
    > while ( ( c1 = fgetc( fp ) ) != EOF )
    > putchar( c1 );
    >
    > #if 0
    > /* or, when using fscanf() */
    >
    > while ( fscanf( fp, "%c", &c2 ) == 1 )
    > putc( c2 )
    >
    > /* or, when using fread() */
    >
    > while ( fread( &c2, 1, 1, fp ) == 1 )
    > putc( c2 )
    > #endif
    >
    > /* Check why the last read failed */
    >
    > if ( feof( fp ) )
    > fprintf( stderr, "End of file detected\n" );
    > else
    > fprintf( stderr, "Read error\n" );
    >
    > #if 0
    > /* or using ferror() */
    >
    > if ( ferror( fp ) )
    > fprintf( stderr, "Read error\n" );
    > else
    > fprintf( stderr, "End of file detected\n" );
    > #endif
    >
    > close( fp );
    > return 0;}
    >


    Can you, or someone else tell me why you are using #if 0 / #endif vs
    just something like if/else,
     
    Chad, Jul 13, 2008
    #14
  15. On Sat, 12 Jul 2008 22:36:38 -0700 (PDT), Chad <>
    wrote:

    >On Jul 12, 4:24 am, (Jens Thoms Toerring) wrote:
    >> Ali Karaali <> wrote:
    >> > On 12 Temmuz, 11:44, santosh <> wrote:
    >> > > > /*the following checks whether fp has exact the same lines, then write
    >> > > > different lines into ftemp*/
    >> > > > while(!feof(fp)){

    >>
    >> > > This is apparently a common beginner error. In C the function feof and
    >> > > ferror should *not* be called *before* an I/O function (like
    >> > > fgetc/fgets etc) has tried to read a stream.

    >>
    >> > > Rather call your I/O function and *if* that function indicates that it
    >> > > has failed (by returning EOF or NULL or as documented), *then* you can
    >> > > call feof or ferror to *disambiguate* between whether the failure was
    >> > > due to end-of-file condition or due to a read error.
    >> > Can you show me source for this?

    >>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >>
    >> int main( void )
    >> {
    >> FILE *fp;
    >> int c1,
    >> char c2;
    >>
    >> if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    >> {
    >> fprintf( stderr, "Failed to open file\n" );
    >> return EXIT_FAILURE;
    >> }
    >>
    >> /* Read until nothing can be read anymore */
    >>
    >> while ( ( c1 = fgetc( fp ) ) != EOF )
    >> putchar( c1 );
    >>
    >> #if 0
    >> /* or, when using fscanf() */
    >>
    >> while ( fscanf( fp, "%c", &c2 ) == 1 )
    >> putc( c2 )
    >>
    >> /* or, when using fread() */
    >>
    >> while ( fread( &c2, 1, 1, fp ) == 1 )
    >> putc( c2 )
    >> #endif
    >>
    >> /* Check why the last read failed */
    >>
    >> if ( feof( fp ) )
    >> fprintf( stderr, "End of file detected\n" );
    >> else
    >> fprintf( stderr, "Read error\n" );
    >>
    >> #if 0
    >> /* or using ferror() */
    >>
    >> if ( ferror( fp ) )
    >> fprintf( stderr, "Read error\n" );
    >> else
    >> fprintf( stderr, "End of file detected\n" );
    >> #endif
    >>
    >> close( fp );
    >> return 0;}
    >>

    >
    >Can you, or someone else tell me why you are using #if 0 / #endif vs
    >just something like if/else,


    The #if 0 suppresses the compilation of that block of code. It's as
    if the code were not present in the source module.

    An if (0) is only required to suppress the execution of the block. An
    optimizing compiler can still optimize it away but there is no
    requirement that it do so.


    Remove del for email
     
    Barry Schwarz, Jul 13, 2008
    #15
  16. In article <>,
    Richard Heathfield <> wrote:

    >just like
    >opening a paint can with a screwdriver


    I've never heard of anyone using anything else. Is there a special
    tool intended for the purpose?

    -- Richard
    --
    Please remember to mention me / in tapes you leave behind.
     
    Richard Tobin, Jul 13, 2008
    #16
  17. kindrain

    Chad Guest

    On Jul 12, 10:47 pm, Barry Schwarz <> wrote:
    > On Sat, 12 Jul 2008 22:36:38 -0700 (PDT), Chad <>
    > wrote:
    >
    >
    >
    > >On Jul 12, 4:24 am, (Jens Thoms Toerring) wrote:
    > >> Ali Karaali <> wrote:
    > >> > On 12 Temmuz, 11:44, santosh <> wrote:
    > >> > > > /*the following checks whether fp has exact the same lines, then write
    > >> > > > different lines into ftemp*/
    > >> > > > while(!feof(fp)){

    >
    > >> > > This is apparently a common beginner error. In C the function feof and
    > >> > > ferror should *not* be called *before* an I/O function (like
    > >> > > fgetc/fgets etc) has tried to read a stream.

    >
    > >> > > Rather call your I/O function and *if* that function indicates that it
    > >> > > has failed (by returning EOF or NULL or as documented), *then* you can
    > >> > > call feof or ferror to *disambiguate* between whether the failure was
    > >> > > due to end-of-file condition or due to a read error.
    > >> > Can you show me source for this?

    >
    > >> #include <stdio.h>
    > >> #include <stdlib.h>

    >
    > >> int main( void )
    > >> {
    > >> FILE *fp;
    > >> int c1,
    > >> char c2;

    >
    > >> if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    > >> {
    > >> fprintf( stderr, "Failed to open file\n" );
    > >> return EXIT_FAILURE;
    > >> }

    >
    > >> /* Read until nothing can be read anymore */

    >
    > >> while ( ( c1 = fgetc( fp ) ) != EOF )
    > >> putchar( c1 );

    >
    > >> #if 0
    > >> /* or, when using fscanf() */

    >
    > >> while ( fscanf( fp, "%c", &c2 ) == 1 )
    > >> putc( c2 )

    >
    > >> /* or, when using fread() */

    >
    > >> while ( fread( &c2, 1, 1, fp ) == 1 )
    > >> putc( c2 )
    > >> #endif

    >
    > >> /* Check why the last read failed */

    >
    > >> if ( feof( fp ) )
    > >> fprintf( stderr, "End of file detected\n" );
    > >> else
    > >> fprintf( stderr, "Read error\n" );

    >
    > >> #if 0
    > >> /* or using ferror() */

    >
    > >> if ( ferror( fp ) )
    > >> fprintf( stderr, "Read error\n" );
    > >> else
    > >> fprintf( stderr, "End of file detected\n" );
    > >> #endif

    >
    > >> close( fp );
    > >> return 0;}

    >
    > >Can you, or someone else tell me why you are using #if 0 / #endif vs
    > >just something like if/else,

    >
    > The #if 0 suppresses the compilation of that block of code. It's as
    > if the code were not present in the source module.
    >
    > An if (0) is only required to suppress the execution of the block. An
    > optimizing compiler can still optimize it away but there is no
    > requirement that it do so.
    >
    > Remove del for email


    Is there a particular advantage to using #if 0 (in this case)? Does
    suppressing the compilation of that block code just make the program
    run faster? Or is there something more?
     
    Chad, Jul 13, 2008
    #17
  18. kindrain

    santosh Guest

    Chad wrote:
    > On Jul 12, 10:47 pm, Barry Schwarz <> wrote:
    >> On Sat, 12 Jul 2008 22:36:38 -0700 (PDT), Chad <>
    >> wrote:
    >> >On Jul 12, 4:24 am, (Jens Thoms Toerring) wrote:


    >> >> #include <stdio.h>
    >> >> #include <stdlib.h>

    >>
    >> >> int main( void )
    >> >> {
    >> >> FILE *fp;
    >> >> int c1,
    >> >> char c2;

    >>
    >> >> if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    >> >> {
    >> >> fprintf( stderr, "Failed to open file\n" );
    >> >> return EXIT_FAILURE;
    >> >> }

    >>
    >> >> /* Read until nothing can be read anymore */

    >>
    >> >> while ( ( c1 = fgetc( fp ) ) != EOF )
    >> >> putchar( c1 );

    >>
    >> >> #if 0
    >> >> /* or, when using fscanf() */

    >>
    >> >> while ( fscanf( fp, "%c", &c2 ) == 1 )
    >> >> putc( c2 )

    >>
    >> >> /* or, when using fread() */

    >>
    >> >> while ( fread( &c2, 1, 1, fp ) == 1 )
    >> >> putc( c2 )
    >> >> #endif

    >>
    >> >> /* Check why the last read failed */

    >>
    >> >> if ( feof( fp ) )
    >> >> fprintf( stderr, "End of file detected\n" );
    >> >> else
    >> >> fprintf( stderr, "Read error\n" );

    >>
    >> >> #if 0
    >> >> /* or using ferror() */

    >>
    >> >> if ( ferror( fp ) )
    >> >> fprintf( stderr, "Read error\n" );
    >> >> else
    >> >> fprintf( stderr, "End of file detected\n" );
    >> >> #endif

    >>
    >> >> close( fp );
    >> >> return 0;}

    >>
    >> >Can you, or someone else tell me why you are using #if 0 / #endif vs
    >> >just something like if/else,

    >>
    >> The #if 0 suppresses the compilation of that block of code. It's as
    >> if the code were not present in the source module.
    >>
    >> An if (0) is only required to suppress the execution of the block.
    >> An optimizing compiler can still optimize it away but there is no
    >> requirement that it do so.


    > Is there a particular advantage to using #if 0 (in this case)? Does
    > suppressing the compilation of that block code just make the program
    > run faster? Or is there something more?


    In this particular case the first set of #if 0 ... #endif is needed,
    otherwise functionality is duplicated. The second pair isn't strictly
    needed.

    In general blocks of code are commented out (with any method) because
    they are either buggy or deemed not necessary or fit for some reason.
    It has nothing to do with runtime speed.
     
    santosh, Jul 13, 2008
    #18
  19. kindrain

    Chad Guest

    On Jul 13, 6:48 am, santosh <> wrote:
    > Chad wrote:
    > > On Jul 12, 10:47 pm, Barry Schwarz <> wrote:
    > >> On Sat, 12 Jul 2008 22:36:38 -0700 (PDT), Chad <>
    > >> wrote:
    > >> >On Jul 12, 4:24 am, (Jens Thoms Toerring) wrote:
    > >> >> #include <stdio.h>
    > >> >> #include <stdlib.h>

    >
    > >> >> int main( void )
    > >> >> {
    > >> >> FILE *fp;
    > >> >> int c1,
    > >> >> char c2;

    >
    > >> >> if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    > >> >> {
    > >> >> fprintf( stderr, "Failed to open file\n" );
    > >> >> return EXIT_FAILURE;
    > >> >> }

    >
    > >> >> /* Read until nothing can be read anymore */

    >
    > >> >> while ( ( c1 = fgetc( fp ) ) != EOF )
    > >> >> putchar( c1 );

    >
    > >> >> #if 0
    > >> >> /* or, when using fscanf() */

    >
    > >> >> while ( fscanf( fp, "%c", &c2 ) == 1 )
    > >> >> putc( c2 )

    >
    > >> >> /* or, when using fread() */

    >
    > >> >> while ( fread( &c2, 1, 1, fp ) == 1 )
    > >> >> putc( c2 )
    > >> >> #endif

    >
    > >> >> /* Check why the last read failed */

    >
    > >> >> if ( feof( fp ) )
    > >> >> fprintf( stderr, "End of file detected\n" );
    > >> >> else
    > >> >> fprintf( stderr, "Read error\n" );

    >
    > >> >> #if 0
    > >> >> /* or using ferror() */

    >
    > >> >> if ( ferror( fp ) )
    > >> >> fprintf( stderr, "Read error\n" );
    > >> >> else
    > >> >> fprintf( stderr, "End of file detected\n" );
    > >> >> #endif

    >
    > >> >> close( fp );
    > >> >> return 0;}

    >
    > >> >Can you, or someone else tell me why you are using #if 0 / #endif vs
    > >> >just something like if/else,

    >
    > >> The #if 0 suppresses the compilation of that block of code. It's as
    > >> if the code were not present in the source module.

    >
    > >> An if (0) is only required to suppress the execution of the block.
    > >> An optimizing compiler can still optimize it away but there is no
    > >> requirement that it do so.

    > > Is there a particular advantage to using #if 0 (in this case)? Does
    > > suppressing the compilation of that block code just make the program
    > > run faster? Or is there something more?

    >
    > In this particular case the first set of #if 0 ... #endif is needed,
    > otherwise functionality is duplicated. The second pair isn't strictly
    > needed.
    >
    > In general blocks of code are commented out (with any method) because
    > they are either buggy or deemed not necessary or fit for some reason.
    > It has nothing to do with runtime speed.



    I don't see how the using something like if# 0 .. #endif removes
    duplicate functionality in this case. Okay, it just hurts to think
    right about now. Maybe in a few hours everything will sink in.
     
    Chad, Jul 13, 2008
    #19
  20. kindrain

    santosh Guest

    Chad wrote:

    > On Jul 13, 6:48 am, santosh <> wrote:
    >> Chad wrote:
    >> > On Jul 12, 10:47 pm, Barry Schwarz <> wrote:
    >> >> On Sat, 12 Jul 2008 22:36:38 -0700 (PDT), Chad <>
    >> >> wrote:
    >> >> >On Jul 12, 4:24 am, (Jens Thoms Toerring) wrote:
    >> >> >> #include <stdio.h>
    >> >> >> #include <stdlib.h>

    >>
    >> >> >> int main( void )
    >> >> >> {
    >> >> >> FILE *fp;
    >> >> >> int c1,
    >> >> >> char c2;

    >>
    >> >> >> if ( ( fp = fopen( "test.txt", "r" ) == NULL )
    >> >> >> {
    >> >> >> fprintf( stderr, "Failed to open file\n" );
    >> >> >> return EXIT_FAILURE;
    >> >> >> }

    >>
    >> >> >> /* Read until nothing can be read anymore */

    >>
    >> >> >> while ( ( c1 = fgetc( fp ) ) != EOF )
    >> >> >> putchar( c1 );

    >>
    >> >> >> #if 0
    >> >> >> /* or, when using fscanf() */

    >>
    >> >> >> while ( fscanf( fp, "%c", &c2 ) == 1 )
    >> >> >> putc( c2 )

    >>
    >> >> >> /* or, when using fread() */

    >>
    >> >> >> while ( fread( &c2, 1, 1, fp ) == 1 )
    >> >> >> putc( c2 )
    >> >> >> #endif

    >>
    >> >> >> /* Check why the last read failed */

    >>
    >> >> >> if ( feof( fp ) )
    >> >> >> fprintf( stderr, "End of file detected\n" );
    >> >> >> else
    >> >> >> fprintf( stderr, "Read error\n" );

    >>
    >> >> >> #if 0
    >> >> >> /* or using ferror() */

    >>
    >> >> >> if ( ferror( fp ) )
    >> >> >> fprintf( stderr, "Read error\n" );
    >> >> >> else
    >> >> >> fprintf( stderr, "End of file detected\n" );
    >> >> >> #endif

    >>
    >> >> >> close( fp );
    >> >> >> return 0;}

    >>
    >> >> >Can you, or someone else tell me why you are using #if 0 / #endif
    >> >> >vs just something like if/else,

    >>
    >> >> The #if 0 suppresses the compilation of that block of code. It's
    >> >> as if the code were not present in the source module.

    >>
    >> >> An if (0) is only required to suppress the execution of the block.
    >> >> An optimizing compiler can still optimize it away but there is no
    >> >> requirement that it do so.
    >> > Is there a particular advantage to using #if 0 (in this case)? Does
    >> > suppressing the compilation of that block code just make the
    >> > program run faster? Or is there something more?

    >>
    >> In this particular case the first set of #if 0 ... #endif is needed,
    >> otherwise functionality is duplicated. The second pair isn't strictly
    >> needed.
    >>
    >> In general blocks of code are commented out (with any method) because
    >> they are either buggy or deemed not necessary or fit for some reason.
    >> It has nothing to do with runtime speed.

    >
    >
    > I don't see how the using something like if# 0 .. #endif removes
    > duplicate functionality in this case. Okay, it just hurts to think
    > right about now. Maybe in a few hours everything will sink in.


    In the code that Jens has presented he use fgetc in a loop to read from
    a file and output characters until EOF is encountered. The code in the
    first pair of #if 0... #endif are simply alternate forms of the same
    read loop using instead of fgetc, fscanf and fread. If they had been
    compiled (i.e., if the #if 0... #endif were absent), they too would be
    executed after the first loop has run it's course. They would most
    probably immediately return end-of-file since after the first loop fp
    is already read.

    This is a case where the #if 0 and #endif are not critical to
    correctness, but generally code that has been preprocessed or commented
    out should not be compiled without a careful review.
     
    santosh, Jul 13, 2008
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,252
    Martien Verbruggen
    Jun 27, 2003
  2. Mantorok Redgormor

    feof usage

    Mantorok Redgormor, Sep 20, 2003, in forum: C Programming
    Replies:
    28
    Views:
    1,170
    Dave Thompson
    Sep 29, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,712
    Old Wolf
    Jan 20, 2004
  4. Joriveek

    feof

    Joriveek, Sep 13, 2005, in forum: C Programming
    Replies:
    8
    Views:
    724
    Keith Thompson
    Sep 14, 2005
  5. problem with feof ?

    , Jan 28, 2013, in forum: C Programming
    Replies:
    21
    Views:
    470
    James Kuyper
    Jan 29, 2013
Loading...

Share This Page