Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

*Might* an unsigned char be equal to EOF? [duplicate]

When using fgetc to read the next character of a stream, you usually check that the end-of-file was not attained by

if ((c = fgetc (stream)) != EOF)

where c is of int type. Then, either the end-of-file has been attained and the condition will fail, or c shall be an unsigned char converted to int, which is expected to be different from EOF —for EOF is ensured to be negative. Fine... apparently.

But there is a small problem... Usually the char type has no more than 8 bits, while int must have at least 16 bits, so every unsigned char will be representable as an int. Nevertheless, in the case char would have 16 or 32 bits (I know, this is never the case in practice...), there is no reason why one could not have sizeof(int) == 1, so that it would be (theoretically!) possible that fgetc (stream) returns EOF (or another negative value) but that end-of-file has not been attained...

Am I mistaken? Is it something in the C standard that prevents fgetc to return EOF if end-of-file has not been attained? (If yes, I could not find it!). Or is the if ((c = fgetc (stream)) != EOF) syntax not fully portable?...

EDIT: Indeed, this was a duplicate of Question #3860943. I did not find that question at first search. Thank for your help! :-)

like image 215
Rémi Peyre Avatar asked Apr 30 '15 19:04

Rémi Peyre


1 Answers

You asked:

Is it something in the C standard that prevents fgetc to return EOF if end-of-file has not been attained?

On the contrary, the standard explicitly allows EOF to be returned when an error occurs.

If a read error occurs, the error indicator for the stream is set and the fgetc function returns EOF.

In the footnotes, I see:

An end-of-file and a read error can be distinguished by use of the feof and ferror functions.

You also asked:

Or is the if ((c = fgetc (stream)) != EOF) syntax not fully portable?

On the theoretical platform where CHAR_BIT is more than 8 and sizeof(int) == 1, that won't be a valid way to check that end-of-file has been reached. For that, you'll have to resort to feof and ferror.

c = fgetc (stream);
if ( !feof(stream) && !ferror(stream) )
{
  // Got valid input in c.
}
like image 58
R Sahu Avatar answered Sep 24 '22 07:09

R Sahu