0
char x[3][3][3]={{"bad","had","rad"},{"bat","cat","hat"},{"hit","git","bit"}};

printf("%s\n", x[1][0]);

Why is the output for this code "batcathathitgitbit" and not just "bat"? I am having difficulty wrapping my head around why it is not just printing one item.

yano
  • 4,827
  • 2
  • 23
  • 35
cedlcc
  • 1
  • What would happen if `char x[3][3][4]=...`? – CristiFati Nov 10 '21 at 23:03
  • Wow that seems to have worked, but I'm still puzzled as to why the output was originally so strange. – cedlcc Nov 10 '21 at 23:04
  • @cedlcc Check out the answers on an old question of mine, explains what happened https://stackoverflow.com/questions/58229351/bizarre-behavior-with-2d-char-array-in-c – Libra Nov 10 '21 at 23:06

3 Answers3

3

Strings must have a null terminator in C, it tells the compiler where to stop parsing for the string. Make every string set one longer so that there is still a null character at the end

char x[3][3][4]={{"bad","had","rad"},{"bat","cat","hat"},{"hit","git","bit"}};

printf("%s\n", x[1][0]);
Libra
  • 2,544
  • 1
  • 8
  • 24
1

Why are you getting this output?

Well, think about the type your printf is taking. You told it you'll pass an %s, i.e. a nul-terminated string, with a const char* argument.

Now think about your 3-dimensional array. How is it actually laid out in memory? As the characters of consecutive cells:

  • x[0][0][0] - that's 'b',

  • x[0][0][0] - that's 'a',

  • x[0][0][2] - that's 'd',

    ... what's next? it's not x[0][0][3], since x's innermost dimension is 3, not 4! So we have no place to put the trailing '\0'. In fact, we now have:

  • x[0][1][0] - that's 'h',

  • x[0][1][1] - that's 'a',

  • etc.

Thus, only the first 3 characters of each string are used, and you get an uninterrupted sequence of characters; the string doesn't even end with the last character in x.

How can you fix this?

Make the innermost dimension large enough to fit all your words: char x[3][3][4]. Then you'll get the expected output (GodBolt).

einpoklum
  • 118,144
  • 57
  • 340
  • 684
0

Simple test program unveiles the memory representation of the 3d array:

int main(void)
{


    char x[3][3][3]={{"bad","had","rad"},{"bat","cat","hat"},{"hit","git","bit"}};
    char *ptr = (char *)x;

    for(size_t i = 0; i < sizeof(x); i++)
    {
        printf("x[%2zu] = '%c'\n", i, ptr[i]);
    }

}
x[ 0] = 'b'
x[ 1] = 'a'
x[ 2] = 'd'
x[ 3] = 'h'
x[ 4] = 'a'
x[ 5] = 'd'
x[ 6] = 'r'
x[ 7] = 'a'
x[ 8] = 'd'
x[ 9] = 'b'
x[10] = 'a'
x[11] = 't'
x[12] = 'c'
x[13] = 'a'
x[14] = 't'
x[15] = 'h'
x[16] = 'a'
x[17] = 't'
x[18] = 'h'
x[19] = 'i'
x[20] = 't'
x[21] = 'g'
x[22] = 'i'
x[23] = 't'
x[24] = 'b'
x[25] = 'i'
x[26] = 't'
0___________
  • 60,014
  • 4
  • 34
  • 74