3

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

Ana Nimbus
  • 635
  • 3
  • 16

2 Answers2

5

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

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • +1 for `k == (unsigned char) c || k == EOF`. I am still doubtful that the standard forbids something other than this, though. Perhaps I am not being clear enough in my "dollar sign" example? – Ana Nimbus Oct 20 '21 at 02:40
  • @AnaNimbus Citation added. `$` example is clear, yet the issue is "is `k == c || k == EOF` **always** true?" – chux - Reinstate Monica Oct 20 '21 at 03:24
2

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.

Brian61354270
  • 8,690
  • 4
  • 21
  • 43
  • Very good choice of citations. – David C. Rankin Oct 20 '21 at 02:16
  • I suppose I am asking for an interpretation, as the language is to me ambiguous. _But will the written character always be equal to the one requested?_ For example, [cppreference.com/fputc](https://en.cppreference.com/w/c/io/fputc) uses the word "success." If I write `fputc('\u0024', stdout)` and the _euro_ sign is written (rather than the dollar sign I specified), 1. does the Standard allow that, 2. would that be "success?" – Ana Nimbus Oct 20 '21 at 02:24
  • Given that `c` is an `int`, and then "The `fputc` function writes the character specified by `c` (converted to an `unsigned char`) ... The `fputc` function returns the character written." the `unsigned char` that gets both written and returned **does not have to equal `c` or `EOF`**. There are many `int` values outside the range of an `unsigned char` that are not equal to `EOF`. – Andrew Henle Oct 20 '21 at 17:36