The crucial point is that c
must be an int
:
int c;
while ((c = getchar()) != EOF) { char read_value = c; /* ... */ }
It is assumed that an int
can hold more values than a char
, or at least more values that the system's narrow multibyte encoding uses*, and getchar
returns a special constant EOF
when there it failed to read more data. Otherwise, it is guaranteed that you can convert c
to a char
and obtain the value of the character that was read.
It is a common mistake to declare c
itself as a char
, in which case the loop might never terminate, since you might not be able to capture the special value EOF
, or otherwise there would be a perfectly valid character which would be indistinguishable from (char)EOF
.
*) For example, it would be perfectly fine if both a char
and an int
were 32 bits wide on a given platform, as long as, say, the narrow stream could only return units with values in the range [-128, 128), and you could use -200
as EOF
.