Reputation:
I have the following code:
FILE *f = fopen('/path/to/some/file', 'rb');
char c;
while((c = fgetc(f)) != EOF)
{
printf("next char: '%c', '%d'", c, c);
}
For some reason, when printing out the characters, at the end of the file, an un-renderable character gets printed out, along with the ASCII ordinal -1.
next char: '?', '-1'
What character is this supposed to be? I know it's not EOF because there's a check for that, and quickly after the character is printed, the program SEGFAULT.
Upvotes: 0
Views: 4520
Reputation: 753695
The trouble is that fgetc()
and its relatives return an int
, not a char
:
If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the
fgetc
function obtains that character as anunsigned char
converted to anint
and advances the associated file position indicator for the stream (if defined).If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of- file indicator for the stream is set and the
fgetc
function returnsEOF
.
It has to return every possible valid character value and a distinct value, EOF
(which is negative, and usually but not necessarily -1
).
When you read the value into a char
instead of an int
, one of two undesirable things happens:
If plain char
is unsigned, then you never get a value equal to EOF, so the loop never terminates.
If plain char
is signed, then you can mistake a legitimate character, 0xFF (often ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS) is treated the same as EOF, so you detect EOF prematurely.
Either way, it is not good.
The fix is to use int c;
instead of .char c;
Incidentally, the fopen()
call should not compile:
FILE *f = fopen('/path/to/some/file', 'rb');
should be:
FILE *f = fopen("/path/to/some/file", "rb");
Always check the result of fopen()
; of all the I/O functions, it is more prone to failure than almost any other (not through its own fault, but because the user or programmer makes a mistake with the file name).
Upvotes: 7
Reputation: 206577
This is the culprit:
char c;
Please change it to:
int c;
The return type of fgetc
is int
, not char
. You get strange behavior when you convert int
to char
in some platforms.
Upvotes: 2