Question

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.

Was it helpful?

Solution

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 an unsigned char converted to an int 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 returns EOF.

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

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

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top