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

K

kindrain

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!
 
S

santosh

kindrain said:
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)

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.
 
K

kindrain

kindrain said:
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)

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.*/
}

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?
 
S

santosh

kindrain wrote:

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>
 
B

Ben Bacarisse

kindrain said:
On Jul 12, 4:44 pm, santosh <[email protected]> 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.
 
A

Ali Karaali

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?
 
V

viza

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 (e-mail address removed) 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;
}
 
J

Jens Thoms Toerring

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
 
S

santosh

Ali said:
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.
 
S

santosh

viza said:
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 (e-mail address removed) 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.
 
V

vippstar

<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)
 
C

Chad

#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,
 
B

Barry Schwarz

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
 
R

Richard Tobin

Richard Heathfield said:
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
 
C

Chad

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?
 
S

santosh

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.
 
C

Chad

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.
 
S

santosh

Chad said:
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.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,835
Latest member
lila30

Latest Threads

Top