What is a trigraph in c ?

A trigraph in C is formed of three characters, the first two characters are interrogation marks ??, and the last character is just a regular character.

ISO 646, standardized ASCII, and made national variants of it. The national variants differed from ASCII, in the way they represented 10 characters, including the 9 characters, that the C standard provided an alternative way of input for, by using trigraphs .

So, on a keyboard that does not have these 9 characters, or have other characters defined at their places, trigraphs can be used as a way for inputing these characters.

There are nine trigraphs in C , and they are:

Trigraph sequenceCharacter
??<{
??>}
??([
??)]
??!|
??/\
??'^
??-~
??=#

Trigraphs can be used anywhere in a C source file, so they can be used in strings, and characters literals, and they can also be used in the C source code. Trigraph replacement is done early on in the compilation process, so it is done before preprocessing.

/*        
trigraph.c
    a Trigraph is simply formed of two interrogation marks 
    followed by a letter . They  are : 
        ??< {
        ??> }
        ??( [
        ??) ]
        ??! |
        ??/ \
        ??' ^
        ??- ~
        ??= #
*/

??=include <stdio.h>

int main( int argc, char * argv[ ] )
??<
    int anIntArray??(3??) = ??< 2 , 3 , 5 ??>;
    printf("anIntArray[0] is : %d ??/n", anIntArray[0]);
    return 0;
??>

/* Output: 
anIntArray[0] is : 2 .*/

gcc can be used to compile a C source file, that contains trigraphs, by using this command:

gcc trigraph.c -trigraphs -Wno-trigraphs

What follows is another example of using trigraphs, and how to escape a trigraph.

#include <stdio.h>

int main( int argc, char  * argv[ ] )
{
    char *cpDoubleQuote = "??/"";
    /* ??\ will be replaced by \ , 
       so you end up with \", 
       which is " .*/

    printf( "*cpDoubleQuote is %s\n", cpDoubleQuote );
    // *cpDoubleQuote is "

    char *cpT = "??/??/t";
    /* ??\ will be replaced by \
       ??\ will be replaced by \
       We end up with \\t, so 
       \\ is \, so we end up 
       with \t .*/

    printf( "*cpT is %s\n" , cpT );
    // *cpT is \t

    printf("%s", "\??(\n");
    /* Placing a backslash before,
       the first interrogation mark, 
       does not escape the trigraph.
       Output: 
       [ 
    */

    printf( "%s", "?\?(\n" );
    /* Placing a backslash after 
       the second interrogation
       mark, escapes the trigraph. 
       Output: 
       ??(
    */
    return 0; }