The overall general question is; Is there some oddity in C regarding string initialization that no one seems to be commenting on that I can find a reference to / Is there some particular Googlemancy term to research an oddity that I have stumbled over / Is it me or is there some sort of "bug" or "feature" in how both printf and strlen appear to handle particular strings in C?
I am finding that while printf is supposed to print a string, it is only printing part of it. I am finding that while strlen is supposed to report the length of a string, it is only reporting part of it.
Have I found some sort of bug, or is this a fairly to very obscure "feature" of C, in which case, what are the details and discussion terms of such a "feature"?
Consider this code, and the subsequent output:
Code:
/* Header files for program support */
#include <stdio.h>
#include <string.h>
/* The primary program section */
int main(void)
{
/* Variable declaration and initialization*/
char aitch[30] = "Cat";
/* What gets done here */
printf("The string aitch is: %s.\n", aitch);
printf("strlen says aitch is %lu characters long.\n", strlen(aitch));
printf("aitch[10] is what is between >> and <<: >>%c<<.\n\n", aitch[10]);
printf("Now dish out a bunch of chopped liver.\n\n");
/* More variable declaration and initialization*/
aitch[11] = ' '; aitch[12] = 'C'; aitch[13] = 'h'; aitch[14] = 'o';
aitch[15] = 'p'; aitch[16] = 'p'; aitch[17] = 'e'; aitch[18] = 'd';
aitch[19] = ' '; aitch[20] = 'l'; aitch[21] = 'i'; aitch[22] = 'v';
aitch[23] = 'e'; aitch[24] = 'r';
/* Looking over the new stuff */
printf("aitch listed by character at this point is:\n\n");
printf("%c", aitch[0]); printf("%c", aitch[1]);
printf("%c", aitch[2]); printf("%c", aitch[3]);
printf("%c", aitch[4]); printf("%c", aitch[5]);
printf("%c", aitch[6]); printf("%c", aitch[7]);
printf("%c", aitch[8]); printf("%c", aitch[9]);
printf("%c", aitch[10]); printf("%c", aitch[11]);
printf("%c", aitch[12]); printf("%c", aitch[13]);
printf("%c", aitch[14]); printf("%c", aitch[15]);
printf("%c", aitch[16]); printf("%c", aitch[17]);
printf("%c", aitch[18]); printf("%c", aitch[19]);
printf("%c", aitch[20]); printf("%c", aitch[21]);
printf("%c", aitch[22]); printf("%c", aitch[23]);
printf("%c", aitch[24]); printf("\n\n");
/* Hang on, what was that last bit? */
printf("printf still says all of aitch is %s.\n", aitch);
printf("strlen still says all of aitch is %lu characters long.\n",
strlen(aitch));
printf("aitch[10] is still what is between >> and <<: >>%c<<.\n\n", aitch[10]);
printf("Now put something in the empty area.\n\n");
/* More variable declaration and initialization*/
aitch[3] = '_'; aitch[4] = '_'; aitch[5] = '_'; aitch[6] = '_';
aitch[7] = '_'; aitch[8] = '_'; aitch[9] = '_'; aitch[10] = '_';
/* Ok, _Now_ what??? */
printf("printf now says all of aitch is:\n\n%s.\n\n", aitch);
printf("strlen says all of aitch _now_ is %lu characters long.\n",
strlen(aitch));
printf("aitch[10] is now what is between >> and <<: >>%c<<.\n\n", aitch[10]);
}
Output:
% ./a.out
The string aitch is: Cat.
strlen says aitch is 3 characters long.
aitch[10] is what is between >> and <<: >><<.
Now dish out a bunch of chopped liver.
aitch listed by character at this point is:
Cat Chopped liver
printf still says all of aitch is Cat.
strlen still says all of aitch is 3 characters long.
aitch[10] is still what is between >> and <<: >><<.
Now put something in the empty area.
printf now says all of aitch is:
Cat________ Chopped liver.
strlen says all of aitch _now_ is 25 characters long.
aitch[10] is now what is between >> and <<: >>_<<.
In C, a string is: a series of characters, ending with a null character (a 0 byte).
char aitch[30] = "Cat";
This declares an array of 30 characters. The first is 'C', the second is 'a', the third is 't', the fourth is null (to end the string), and the rest are null (by default). (Note: char aitch[30];
by itself wouldn't make them all null)
So you have space for 30 characters. And if you use the space starting from the first character, there's a valid string stored in that space: 'C', 'a', 't', 0. That's a string which is 3 characters long. If you call strlen
it will return 3 because that's how long the string is. If you print it, it prints 3 characters because that's how long the string is.
Note that having space for 30 characters isn't the same thing as having a 30-character string. The space is the space, the string is the data you actually store there. You have 26 characters that aren't part of a string, that you could use if you wanted.
In fact, you have enough space to store two different strings! Which is exactly what you are doing in your code.
And if you make sure there are no null bytes between them, they become one string again.
Note that any "ending part" of a string is also a valid string. If you start from position 0 in your array you get the string "Cat". But if you start from position 1 you get "at", if you start from position 2 you get "t" and if you start from position 3 you get "". All perfectly fine to use.