problem with Data Files

A

alice

hi all,
What will happen when I tries to input a character from a file
which is finished, in other words what will 'c' contains after the last
statement in the following code is executed :

FILE * file =fopen("FILE1.c","r");
char c;
while((c=fgetc(file)) != EOF);
c=fgetc(file);
// what is value of c now???????????????????
Thanks,
Alice
 
L

Lawrence Kirby

hi all,
What will happen when I tries to input a character from a file
which is finished, in other words what will 'c' contains after the last
statement in the following code is executed :

FILE * file =fopen("FILE1.c","r");
char c;
while((c=fgetc(file)) != EOF);

This is incorrect, c needs to be defined as int. fgetc() returns int and
EOF is not guaranteed to be representable as a char. If it is it won't be
distinct from all possible char values.
c=fgetc(file);
// what is value of c now??????????????????? Thanks,

Probably EOF again, maybe something else if the end-of-file condition
cleared in the meantime. End-of-file condition can be sticky but it
doesn't have to be. If you want to attempt further file I/O after
end-of-file is indicated you should perform a file seek operation if that
is appropriate or else call clearerr(). You should not simply attempt
another read operation.

Lawrence
 
P

pete

alice said:
hi all,
What will happen when I tries to input a character from a file
which is finished,
in other words what will 'c' contains after the last
statement in the following code is executed :

FILE * file =fopen("FILE1.c","r");
char c;
while((c=fgetc(file)) != EOF);
c=fgetc(file);
// what is value of c now???????????????????

(char)EOF
 
B

bhanu

Try this program: EOF is always -1, not any negative number.
#include <stdio.h>

int main()
{

FILE * file;
char c;

if((file=fopen("Test.txt","wb")) == NULL)
{
printf("error in opening the file");
return 0;
}

for(c = -10; c < 10; c++)
fputc(c, file);

fclose(file);

if((file=fopen("Test.txt","rb")) == NULL)
{
printf("error in opening the file");
return 0;
}

while((c=fgetc(file)) != EOF)
{
printf("\nc = %d", c);
}

c=fgetc(file);
printf("\n'c' After EOF = %d", c);

printf("\n");

fclose(file);
return 0;
}

Output:


c = -10
c = -9
c = -8
c = -7
c = -6
c = -5
c = -4
c = -3
c = -2
'c' After EOF = 0
 
M

Mike Wahler

bhanu said:
Try this program: EOF is always -1,

It might be for a given compiler, it easily might not
be for others. The language imposes no requirement
that it be -1, only that it is an integer less than zero,
i.e. between INT_MIN and -1.

[snip code, which does not prove that EOF is always -1]

-Mike
 
C

CBFalconer

alice said:
What will happen when I tries to input a character from a file
which is finished, in other words what will 'c' contains after
the last statement in the following code is executed :

FILE * file =fopen("FILE1.c","r");
char c;
while((c=fgetc(file)) != EOF);
c=fgetc(file);
// what is value of c now???????????????????

First of all c must be of type int, not char. EOF is outside the
range of chars. With that change, your final c will _probably_ be
EOF, since most disk files have what is called sticky eof. If the
input file happens to be a terminal, it may not have sticky EOF and
anything can happen.

Your code is more clearly written using "continue;" in place of the
raw ";" in the while loop, and the judicious use of blanks to
separate items improves readability.
 
K

Keith Thompson

bhanu said:
Try this program: EOF is always -1, not any negative number.
[snip]

C99 7.19.1p3, describing the standard header <stdio.h>, says:

The macros are
[...]
EOF

which expands to an integer constant expression, with type int and a
negative value, that is returned by several functions to indicate
end-of-file, that is, no more input from a stream;
[...]

The behavior of the program you posted is consistent with this. An
implementation with EOF==-2 or EOF==-20000 would also be consistent
with the standard.

(I'm assuming that your program correctly demonstrates that EOF==-1
for a given implementation; I haven't actually confirmed this.)
 
K

Keith Thompson

CBFalconer said:
First of all c must be of type int, not char. EOF is outside the
range of chars. With that change, your final c will _probably_ be
EOF, since most disk files have what is called sticky eof. If the
input file happens to be a terminal, it may not have sticky EOF and
anything can happen.

EOF may be (and probably is) within the range of type char if char
happens to be signed, but that's beside the point. The value returned
by fgetc() is either an *unsigned* char converted to int, or EOF.

Figuring out what problems can occur when the result of fgetc() is
stored in a char is fairly complex (and is probably a good exercise
for an intermediate student). Fixing the code so you don't have to
worry about those problems in the first place is easy.
 
C

Chris Torek

Try this program: EOF is always -1, not any negative number.
[most of program snipped; but here are the key parts]
char c;
while((c=fgetc(file)) != EOF)
{
printf("\nc = %d", c);
}

c=fgetc(file);
printf("\n'c' After EOF = %d", c);

I tried this and got:

c = 255
c = 255
c = 255
c = 255
c = 255
c = 255
... [output repeats forever]

Can you guess why? (Hint: I did not use an Intel 80x86. In fact,
I ran this on a PowerPC system.)

C guarantees that EOF is "#define"d in <stdio.h> as a negative
integer, but -1 is not required, just typical. (The implementation
I used, on which this demonstration program failed, does in fact
define EOF as -1, so that was not the problem.)

C does not guarantee that plain "char" is signed, and in this case,
it is not.
 
K

Keith Thompson

bhanu said:
Try this program: EOF is always -1, not any negative number.
[snip]

Something else I've thought of:

The standard says that EOF expands to an integer constant expression,
with type int and a negative value. It doesn't say or imply that its
value is -1. But I'd be (mildly) surprised if there were any existing
implementation that has a value other than -1 for EOF. For one thing,
it can make the implementation of the functions in <ctype.h> a little
easier.

But well-written code won't break on a hypothetical implementation
with EOF==INT_MIN.
 
C

CBFalconer

Keith said:
bhanu said:
Try this program: EOF is always -1, not any negative number.
[snip]

Something else I've thought of:

The standard says that EOF expands to an integer constant expression,
with type int and a negative value. It doesn't say or imply that its
value is -1. But I'd be (mildly) surprised if there were any existing
implementation that has a value other than -1 for EOF. For one thing,
it can make the implementation of the functions in <ctype.h> a little
easier.

But well-written code won't break on a hypothetical implementation
with EOF==INT_MIN.

We should be able to confuse readers by replacing:

while (EOF != (ch = getchar()) {
/* process stuff */
}
with
while ((ch = getchar()) >= 0) {
/* process stuff */
}
or
do { /* much hairier, not input proof, assumes Ascii */
while ((ch = getchar()) > \'n') {
/* process stuff */
}
/* process eoln */
} while (ch >= 0);
 
J

junky_fellow

Keith said:
bhanu said:
Try this program: EOF is always -1, not any negative number.
[snip]

Something else I've thought of:

The standard says that EOF expands to an integer constant expression,
with type int and a negative value. It doesn't say or imply that its
value is -1. But I'd be (mildly) surprised if there were any existing
implementation that has a value other than -1 for EOF. For one thing,
it can make the implementation of the functions in <ctype.h> a little
easier.

Why there's a requirement to expand EOF to an integer constant (with
type
int and negative value) ? If we see the ASCII character set, the max
value
is 0x7f. So, we can easily represent EOF to be -1 (0xff). Why does the
standard expand EOF to integer type.
 
K

Keith Thompson

Keith said:
bhanu said:
Try this program: EOF is always -1, not any negative number.
[snip]

Something else I've thought of:

The standard says that EOF expands to an integer constant
expression, with type int and a negative value. It doesn't say or
imply that its value is -1. But I'd be (mildly) surprised if there
were any existing implementation that has a value other than -1 for
EOF. For one thing, it can make the implementation of the
functions in <ctype.h> a little easier.

Why there's a requirement to expand EOF to an integer constant (with
type int and negative value) ? If we see the ASCII character set,
the max value is 0x7f. So, we can easily represent EOF to be -1
(0xff). Why does the standard expand EOF to integer type.

-1 is an integer constant with type int and negative value.

If you're suggesting that EOF could be a character value, that
wouldn't work. The standard doesn't assume the ASCII character set;
there are conforming C implementations with different character sets.
And if you're reading a binary file, 0xff is a valid input value.

EOF has to be distinct from all possible character values. This is
done by having fgetc() return an int that's either an *unsigned* char
value converted to int, or EOF.

(The standard probably could have required EOF to be -1, rather than
any arbitrary negative value, but it didn't.)
 
E

Eric Sosman

Keith said:
The standard says that EOF expands to an integer constant expression,
with type int and a negative value. It doesn't say or imply that its
value is -1. But I'd be (mildly) surprised if there were any existing
implementation that has a value other than -1 for EOF. For one thing,
it can make the implementation of the functions in <ctype.h> a little
easier.

An implementation that defined EOF as the value of
CHAR_MIN-1 (or even SCHAR_MIN-1) could allow the <ctype.h>
implementation to be more tolerant of a common error.
Whether such tolerance is a good idea is debatable, but an
implementor might well have the goal of running as many
programs as possible with as little trouble as possible,
whether those programs are faulty or not. Market pressures
sometimes favor convenience over strictness.
 
R

Richard Bos

CBFalconer said:
We should be able to confuse readers by replacing:

while (EOF != (ch = getchar()) {
/* process stuff */
}
with
do { /* much hairier, not input proof, assumes Ascii */
while ((ch = getchar()) > \'n') {

Assumes even more. It assumes no characters smaller than '\n' will
appear in the input. On ASCII systems on which '\n' equals 13, the page
feed character is smaller than it. I semi-regularly enter that character
at my console. I can also imagine people wanting to enter '\a', which on
an ASCII system is smaller than either option for '\n'.

Richard
 
K

Keith Thompson

Assumes even more. It assumes no characters smaller than '\n' will
appear in the input. On ASCII systems on which '\n' equals 13, the page
feed character is smaller than it. I semi-regularly enter that character
at my console. I can also imagine people wanting to enter '\a', which on
an ASCII system is smaller than either option for '\n'.

All of which, I think, is already covered by "not input proof".
 
L

lawrence.jones

Lawrence Kirby said:
Probably EOF again, maybe something else if the end-of-file condition
cleared in the meantime. End-of-file condition can be sticky but it
doesn't have to be.

The C Standard has always required it to be sticky. Some (perhaps even
many) implementations still get it wrong.

-Larry Jones

I don't need to do a better job. I need better P.R. on the job I DO.
-- Calvin
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top