Reputation: 91068
I am a little confused by the following C code snippets:
printf("Peter string is %d bytes\n", sizeof("Peter")); // Peter string is 6 bytes
This tells me that when C compiles a string in double quotes, it will automatically add an extra byte for the null terminator.
printf("Hello '%s'\n", "Peter");
The printf
function knows when to stop reading the string "Peter" because it reaches the null terminator, so ...
char myString[2][9] = {"123456789", "123456789" };
printf("myString: %s\n", myString[0]);
Here, printf
prints all 18 characters because there's no null terminators (and they wouldn't fit without taking out the 9's). Does C not add the null terminator in a variable definition?
Upvotes: 6
Views: 4882
Reputation: 54421
If you tell C that an array is a given size, C cannot make the array any larger. It would be disobeying you if it did so! Remember that not every char array contains a null terminated string. Sometimes the array (as used) is truly an array of (individual) char. The compiler doesn't know what you are doing and cannot read your mind.
This is why C allows you to initialize a char array where the null terminator won't fit but everything else will. Try your example with a string one byte longer and the compiler will complain.
Note that your example will compile but will not do what you expect, as the contents are not (null terminated) strings. With GCC, running your example, I see the string I should, followed by garbage.
Upvotes: 3
Reputation: 84922
C allows unterminated strings, C++ does not.
C allows character arrays to be initialized with string constants. It also allows a string constant initializer to contain exactly one more character than the array it initializes, i.e., the implicit terminating null character of the string may be ignored. For example:
char name1[] = "Harry"; // Array of 6 char char name2[6] = "Harry"; // Array of 6 char char name3[] = { 'H', 'a', 'r', 'r', 'y', '\0' }; // Same as 'name1' initialization char name4[5] = "Harry"; // Array of 5 char, no null char
C++ also allows character arrays to be initialized with string constants, but always includes the terminating null character in the initialization. Thus the last initializer (name4) in the example above is invalid in C++.
Upvotes: 2
Reputation: 17211
Alterenatively, you can use:
char* myString[2] = {"123456789", "123456789" };
Like this, the initializer computes the right size for your null terminated strings.
Upvotes: 2
Reputation: 274
The '\0' byte isn't it's problem. Most of the time, if you have this:
char code[9] = "123456789";
The next byte will be off the edge of the variable, but will be unused memory, and will most likely be 0 (unless you malloc()
and don't set the values before using them). So most of the time it works, even if it's bad for you.
If you're using gcc, you might also want to use the -Wall flag, or one of the other (million) warning flags. This might help (not sure).
Upvotes: 0
Reputation: 91068
Is there a reason why the compiler doesn't warn that there isn't enough room for the 0 byte? I get a warning if I try to add another '9' that won't fit, but it doesn't seem to care about dropping the 0 byte?
Upvotes: 0
Reputation: 120704
Sure it does, you just aren't leaving enough room for the '\0' byte. Making it:
char string[2][10] = { "123456789", "123456789" };
Will work as you expect (will just print 9 characters).
Upvotes: 6
Reputation: 274
Your string is [2][9]. Those [9] are ['1', '2', etc... '8', '9']. Because you only gave it room for 9 chars in the first array dimension, and because you used all 9, it has no room to place a '\0' character. redefine your char array:
char string[2][10] = {"123456789", "123456789"};
And it should work.
Upvotes: 25