cnewlinestdiotrigraphs

Are trigraphs required to write a newline character in C99 using only ISO 646?


Assume that you're writing (portable) C99 code in the invariant set of ISO 646. This means that the \ (backslash, reverse solidus, however you name it) can't be written directly. For instance, one could opt to write a Hello World program as such:

%:include <stdio.h>
%:include <stdlib.h>

int main()
<%
    fputs("Hello World!??/n", stdout);
    return EXIT_SUCCESS;
%>

However, besides digraphs, I used the ??/ trigraph to write the \ character.

Given my assumptions above, is it possible to either

  1. include the '\n' character (which is translated to a newline in <stdio.h> functions) in a string without the use of trigraphs, or
  2. write a newline to a FILE * without using the '\n' character?

Solution

  • Your premise:

    Assume that you're writing (portable) C99 code in the invariant set of ISO 646. This means that the \ (backslash, reverse solidus, however you name it) can't be written directly.

    is questionable. C99 defines "source" and "execution" character sets, and requires that both include representations of the backslash character (C99 5.2.1). The only reason I can imagine for an effort such as you describe would be to try to produce source code that does not require character set transcoding upon movement among machines. In that case, however, the choice of ISO 646 as a common baseline is odd. You're more likely to run into an EBCDIC machine than one that uses an ISO 646 variant that is not coincident with the ISO-8859 family of character sets. (And if you can assume ISO 8859, then backslash does not present a problem.)

    Nevertheless, if you insist on writing C source code without using a literal backslash character, then the trigraph for that character is the way to do so. That's what trigraphs were invented for. In character constants and string literals, you cannot portably substitute anything else for \n or its trigraph equivalent, ??/n, because it is implementation-dependent how that code is mapped. In particular, it is not safe to assume that it maps to a line-feed character (which, however, is included among the invariant characters of ISO 646).

    Update:

    You ask specifically whether it is possible to

    include the '\n' character (which is translated to a newline in functions) in a string without the use of trigraphs, or

    No, it is not possible, because there is no one '\n' character. Moreover, there seems to be a bit of a misconception here: \n in a character or string literal represents one character in the execution character set. The compiler is therefore responsible for that transformation, not the stdio functions. The stdio functions' responsibility is to handle that character on output by writing a character or character sequence intended to produce the specified effect ("[m]oves the active position to the initial position of the next line").

    You also ask whether it is possible to

    write a newline to a FILE * without using the '\n' character?

    This one depends on exactly what you mean. If you want to write a character whose code in the execution character set you know, then you can write a numeric constant having that numeric value. In particular, if you want to write the character with encoded value 0xa (in the execution character set) then you can do so. For example, you could

    fputc(0xa, my_file);
    

    but that does not necessarily produce a result equivalent to

    fputc('\n', my_file);