In C, when may `fputc` return other than its first argument?

Viewed 111

The C17 (N2176) standard states, "The fputc function returns the character written" (7.21.7.3) if there is no write error.

But in the context of

int c ;
// ... later, c is assigned an "interesting" value ...
int k = fputc ( c , stdout ) ;

is

k == c || k == EOF

always true? I.e., provided that fputc does not return EOF, is it guaranteed to return c? Put a third way, can fputc write a character other than one equal to its first argument?

For example If I request output of the dollar sign (not guaranteed to be in the source or execution character sets, AFAICT), could '\u0024' != fputc('\u0024', stdout). Maybe the program will output a local currency symbol, instead.

Clarification

The question is

In C, when may fputc return other than its first argument?

Partial answers so far (2021-10-20) seem to be:

  • when a write error occurs during fputc,
  • when (unsigned char) c != c

I am still wondering

Suppose (unsigned char) c == c, but (unsigned char) c does not match a character in the execution character set. Is fputc permitted to write some other character instead?

For example, suppose c == (unsigned char) '\u0024' (ASCII dollar sign) does not exist in the execution character set (because execution character set is non-ASCII). Can fputc write, say, another currency symbol instead (or some arbitrary character).

2 Answers

is k == c || k == EOF always true?

Usually yes, but no.

With fputc ( c , stdout ), c is converted to an unsigned char and that is written. It is that value or EOF that is returned.

Instead, expect k == (unsigned char) c || k == EOF.

The fputc function writes the character specified by c (converted to an unsigned char) to the output stream ...
Returns: The fputc function returns the character written. If a write error occurs, the error indicator for the stream is set and fputc returns EOF. C17dr § 7.21.7.3 2-3


A somewhat not-so-rare example is when ch is assigned from a char that is signed and with a value less than 0. The function return value is expected to be [0...UCHAR_MAX] or EOF.

Example

char ch = -96;
printf("%d %d %d\n", SCHAR_MIN, ch, fputc(ch, stdout));

Output

�-128 -96 160

Maybe the program will output a local currency symbol, instead.

With fputc('\u0024', stdout), same as fputc(0x24, stdout) and fputc(36, stdout), what symbol is seen is implementation specific. C does not specify that ASCII is used, even if it is ubiquitous. C does not specify the font nor shapes of character renderings. Still, likely will be $.

Yes, fputc always returns either EOF or the written character.

Per cppreference.com's page on fputc:

Return value
On success, returns the written character.
On failure, returns EOF and sets the error indicator (see ferror()) on stream.

And from the C17 standard (7.21.7.3/2-3, N2310):

  1. Description
    The fputc function writes the character specified by c (converted to an unsigned char) to the output stream pointed to by stream ...

  2. Returns
    The fputc function returns the character written. If a write error occurs, the error indicator for the stream is set and fputc returns EOF.

Related