Search code examples
cprintffputs

Print char array with fputs or other - C


The first array prints all right. test[] =
However, when the array is like in the second example, test[][] ={"...","..."};
I get an incompatible warning.
In the second example with fputs, it prints without a line break and with printf, nothing prints.

#include <stdio.h>
//String to display Test
const char test[] =
"|T|\n\
|E|\n\
|S|\n\
|T|\n\
";

int main(){
   //Print test
   fputs(test,stdout);
   printf("\n");
   return 0;
}

Second example.

#include <stdio.h>
#define LINE 4
#define COLN 5
//String to display Test
const char test[LINE][COLN] ={
" |T| ",
" |E| ",
" |S| ",
" |T| "
};

int main(){
    // Print test
    //printf("%s", test);
    fputs(test,stdout);
    printf("\n");
    return 0;
}

Warnings

_______________________________________________________________________________
field width should have type 'int', but argument has type 'const char (*)[11]'
[-Wformat]           printf("%*s",test);
                              ~^   ~~~
_______________________________________________________________________________
incompatible pointer types passing 'const char[11][11]' 
to parameter of type 'const char ' [-Wincompatible-pointer-types]
fputs(test,stdout);
      ^~~~
passing argument to parameter '__s' here
int fputs(const char __s, FILE* __fp);
                      ^

Solution

  • In the lines

    const char test[LINE][COLN] ={
    " |T| ",
    " |E| ",
    " |S| ",
    " |T| "
    };
    

    you are defining an array of 4 char arrays which are not null-terminated (because you defined the array in such a way that there is no room for a null terminating character).

    Therefore, in order to print any of these 4 char arrays, you cannot use fputs. You can, however, use the %s conversion format specifier with printf, but you must limit the number of characters written, for example by using the following syntax:

    printf( "%.*s\n", COLN, test[0] );
    

    See the documentation for printf for further information.

    If you also want to be able to use fputs on the individual char arrays, then you will have to define the char arrays in such a way that there is room for a terminating null character, for example like this:

    const char test[LINE][COLN+1] = {
        " |T| ",
        " |E| ",
        " |S| ",
        " |T| "
    };
    

    However, in order to print all 4 char arrays, you cannot simply use the line

    fputs(test,stdout);
    

    as you are doing in your code, because you can only print one string at a time. Therefore, you must write

    fputs( test[0], stdout );
    printf( "\n" );
    fputs( test[1], stdout );
    printf( "\n" );
    fputs( test[2], stdout );
    printf( "\n" );
    fputs( test[3], stdout );
    printf( "\n" );
    

    in order to print all 4 strings, or better, use a loop:

    for ( int i = 0; i < LINE; i++ )
    {
        fputs( test[i], stdout );
        printf( "\n" );
    }
    

    Regarding your first example, it is worth noting that

    const char test[] =
    "|T|\n\
    |E|\n\
    |S|\n\
    |T|\n\
    ";
    

    is not good coding style, because it would be better to indent all lines except for the first one. You are probably not doing this because this would cause the indentation to become part of the string. However, this problem can be solved by writing the following instead:

    const char test[] =
        "|T|\n"
        "|E|\n"
        "|S|\n"
        "|T|\n";
    

    The preprocessor will concatenate all 4 string literals into a single string literal in phase 6 of the translation process.