1

I want to write a C program that stores a bunch of sentences while it's running and prints them out at the end of the program. Here's what I wrote:

#include<string.h>
#include<stdio.h>

int main(){
    int counter = 0;
    char state[100][200];
    char stroo[3] = "yes";
    sprintf(state[counter], "%s", stroo);
    counter++;
    char poo[2] = "44";
    sprintf(state[counter], "%s", poo);
    counter++;
    for (int i=0; i<counter; i++) {
        printf("%s\n", state[i]);
    }
    return 0;
}

For the output, the first line prints "yes" which is what I expected. The second line, however, prints "44yes". Why is it printing "yes" as well as "44"?

  • We now have a missing null terminator FAQ. Linked as duplicate. – Lundin Nov 18 '19 at 10:42
  • The reason for the unexpected output is that, both the character arrays stroo and poo are not null terminated. Further the reason for getting "44yes" in the second line is that the stack memory is growing downwards and the character arrays have been allocated consecutive memory locations. – Darshan b Nov 19 '19 at 03:27

2 Answers2

2

That's because your strings aren't correctly null-terminated, so you run into undefined behavior at the sprintf. This is because the buffer is too small to hold the null-terminator. For instance here:

char stroo[3] = "yes";

You need memory for four chars, the 'y', 'e', 's' and the null-terminator. Change it to

char stroo[4] = "yes";

Likewise char poo[2] needs to be char poo[3].

See here (emphasis mine):

Successive bytes of the string literal or wide characters of the wide string literal, including the terminating null byte/character, initialize the elements of the array [...] If the size of the array is known, it may be one less than the size of the string literal, in which case the terminating null character is ignored:

If you want the size to automatically be big enough to exactly fit the string, you can just leave out the size specification:

char stroo[] = "yes";

And of course, for this example, you don't even need to copy the string to the stack:

char *stroo = "yes";
Blaze
  • 16,736
  • 2
  • 25
  • 44
  • 2
    Even better would be to just remove the size specification for these. E.g `char stroo[] = "yes";` would allocate the necessary size all by itself. – Jens Gustedt Nov 18 '19 at 09:38
1
#define STRINGS 5
#define STRING_SIZE 50

char arr[STRINGS][STRING_SIZE] =
{ "Hi",
  "Hello world",
  "Good morning",
  "ASDF",
  "QWERTY"
};

for (int i=0; i<STRINGS; i++) {
    printf("%s\n", arr[i]);
}
Refael
  • 6,753
  • 9
  • 35
  • 54