Home > database >  Print char array with fputs or other - C
Print char array with fputs or other - C

Time:08-13

The first array prints all right. test[] =
However, when the array is like in the second example, test[][] ={"...","..."};
I get an incopative 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);
                      ^

CodePudding user response:

The following code works.

  1. increase COLN to 6, because end of string is declared by '\0'.
  2. access individual strings in test by using [i] (i=0 ... 3)
    #define LINE 4
    #define COLN 6
    #include <stdio.h>
    //String to display Test
    const char test[LINE][COLN] ={
    " |T| ",
    " |E| ",
    " |S| ",
    " |T| "
    };
    
    int main(){
        // Print test
        printf("%s\n", test[0]);
        printf("%s\n", test[1]);
        printf("%s\n", test[2]);
        printf("%s\n", test[3]);
        printf("\n");
        return 0;
    }
    
    ./a.out
     |T| 
     |E| 
     |S| 
     |T| 
    

CodePudding user response:

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.

CodePudding user response:

You're experimenting with strings and arrays of strings.

(It's not good practice to 'escape' the newline as you did in your first example. The compiler will "join up" strings from the source code as written in the first example below.)

As others have already said, your second example requires some kind of loop to step through each of the separated strings.

Here's something to study...

// These 'fragments' will be 'connected' at compilation time
const char test1[] = "|T|\n"
                     "|E|\n"
                     "|S|\n"
                     "|T|\n";

// Equivalent
const char test2[] = "|T|\n|E|\n|S|\n|T|\n";

const char *test3[] = { "|T|", "|E|", "|S|", "|T|" };

int main() {
    puts( "test 1:" );  // puts() appends its own '\n'
    puts( test1 );

    puts( "test 2:" );
    puts( test2 );

    puts( "test 3:" );
    for( int i = 0; i < 4; i   )
        puts( test3[i] );

    return 0;
}

Output:

test 1:
|T|
|E|
|S|
|T|

test 2:
|T|
|E|
|S|
|T|

test 3:
|T|
|E|
|S|
|T|

EDIT:

With more information about what the OP is trying to achieve, I provide the following for educational purposes...

#define COLN 11
// String to display Rocket
const char rocket[] = 
    "     ^     "
    "    /^\\    "
    "    |-|    "
    "    | |    "
    "    |W|    "
    "    |E|    "
    "    |E|    "
    "    |E|    "
    "   /| |\\   "
    "  / | | \\  "
    " |  | |  | ";

int main() {
    for( int i = 0; rocket[i]; i  = COLN )
        puts( rocket   i );
    return 0;
}
  • Related