1

I need to print elements of an array of strings, each element consisting of a single character. Generally a 1-D char array could be used but in my case I need to use strings to store these.

I've tried the same code with each element being longer than one character and it seemed to work, however with singular characters I can't figure it out.

void hands(){
    char suits[4][1] = {"A", "K", "Q", "J"};
    printf("%s", suits[0]);
}

I'd expect an output of "A", instead I get "AKQJ {;W?"

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Peter Jordanson
  • 61
  • 2
  • 16
  • 3
    Try `suits[4][2]` to also make space for the null-terminator. *"Generally a 1-D char array could be used but in my case I need to use strings to store these"* from the snippet that you posted, it's not evident why a `char` wouldn't do the job. All you do is printing them, which you can do with chars as well. As it is currently, your (fixed) code is equivalent to `int main(){printf("A");}`. – Blaze Oct 22 '19 at 14:06
  • This are NUL-terminated strings. The second array dimension must be at least 2. – Thomas Jager Oct 22 '19 at 14:06
  • 1
    They *won't* be NUL-terminated strings, there was no room for the `NUL`. Since the elements of an array are contiguous, the `printf` runs through them without finding a `NUL` but eventually finds one *somewhere else.* – Weather Vane Oct 22 '19 at 14:07
  • @Blaze you can post it as answer I guess, since you've been the first one to catch this – Cid Oct 22 '19 at 14:09
  • " but in my case I need to use strings to store these." Why? – Karl Knechtel Oct 22 '19 at 14:10
  • @KarlKnechtel there could be `"10"` I guess in the cards – Cid Oct 22 '19 at 14:11
  • 1
    @Cid I figured it would be a duplicate, but Vlad posted a good answer now. :) – Blaze Oct 22 '19 at 14:11
  • 1
    @Lundin The proposed duplicate doesn't match the question at all. – Ctx Oct 22 '19 at 14:14
  • @Ctx I'm still searching for a good one. Basically we need "Are strings null terminated in C?" and the answer should be "Yes, they are. Allocate room for them." This is a FAQ, I answered it the other day [here](https://stackoverflow.com/questions/58428098/why-does-c-need-array-of-6-size-to-store-5-letter-word-whereas-c-allows-just-5/58428179#58428179) but with a C++ aspect. – Lundin Oct 22 '19 at 14:17
  • Couldn't find one but I can write a community wiki FAQ about how to allocate room for null termination when using strings in C. – Lundin Oct 22 '19 at 15:04
  • I now wrote a community wiki FAQ here: https://stackoverflow.com/questions/58526131/what-are-strings-and-how-to-use-them. Changing dupe target. – Lundin Oct 23 '19 at 15:20

2 Answers2

5

Either declare the array like

void hands(){
    char suits[4][2] = {"A", "K", "Q", "J"};
    printf("%s", suits[0]);
}

to reserve one more character to the terminating zero characters of the string literals.

Or declare the array of pointers to the string literals like

void hands(){
    char * suits[4] = {"A", "K", "Q", "J"};
    printf("%s", suits[0]);
}

If the array is not changed in the function then prefix its declaration with the qualifier const. For example

void hands(){
    const char suits[4][2] = {"A", "K", "Q", "J"};
    printf("%s", suits[0]);
}

Using this declaration of the array as in your question

void hands(){ char suits[4][1] = {"A", "K", "Q", "J"}; printf("%s", suits[0]); }

then instead of the conversion specifier %s use the conversion specifier %c.

printf("%c", suits[0][0] );

Or you may leave the conversion specifier %s but with modifiers like

printf("%1.1s", suits[0]);
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

If you insist on the "string" arrays being 1 character long, there won't be room for a null terminator (that would require the arrays to be at least 2 characters long). In that case, your options are:

  1. print with a "precision" of 1:

    printf("%.1s", suits[0]);
    
  2. print as a character:

    printf("%c", suits[0][0]);   
    
Ian Abbott
  • 15,083
  • 19
  • 33