0

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);
                      ^
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Cmistry
  • 173
  • 7
  • 1
    Just to clarify: the "second" array is called a matrix or a 2 dimensional array – mikyll98 Aug 13 '22 at 01:06
  • With `fputs(test,stdout);`, `fputs()` expects `test` to point to a _string_. Neither `test`, nor `test[0]` are _strings_. Result: undefined behavior (UB). 1st step, provide room in `test[][]` for the _null characters_. – chux - Reinstate Monica Aug 13 '22 at 04:18
  • UV for well formed question with the relevant error listing. – chux - Reinstate Monica Aug 13 '22 at 04:21
  • The first posted warning message does not correspond to your posted code. That warning message is referring to `printf("%*s",test);`, which does not exist in your posted code. There is a similar statement in the code which has been commented out, but that statement is not using `*` in the format string. – Andreas Wenzel Aug 13 '22 at 05:03

3 Answers3

2

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.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • @Cmistry: In your code, you are printing lines `0` to `11`, which is `12` lines. You want to print `11` lines instead. Change the line `for (int i = 0; i<=LINE; i++){` to `for (int i = 0; i – Andreas Wenzel Aug 13 '22 at 03:12
  • Yes, I got it with %.*s, see the output in the online compiler [link](http://codepad.org/hIvhFPhh). very good thanks s2 <3 I noticed here, and your comment hadn't updated before deleting the previous one. – Cmistry Aug 13 '22 at 03:14
  • @Cmistry: Yes, I believe it can take up to about 40 seconds to be notified of other people's comments, and for edits to other people's comments to become visible, it is often necessary for some other action to occur, such as loading new comments or reloading the page. – Andreas Wenzel Aug 13 '22 at 03:19
0

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| 
    
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
sidcoder
  • 460
  • 2
  • 6
0

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;
}
Fe2O3
  • 6,077
  • 2
  • 4
  • 20
  • Test 3 was the closest to what I'm trying to do, but it wasn't a two-dimensional array. see the compiled output at the [link](http://codepad.org/1aeep6kw) – Cmistry Aug 13 '22 at 02:30
  • @Cmistry I've edited and added a solution... The code you linked makes no sense trying to achieve the output desired. – Fe2O3 Aug 13 '22 at 02:55
  • Very good thanks – Cmistry Aug 13 '22 at 03:07