I have recently started learning C and I got into this problem where printf() prints an array I didn't ask for. I was expecting an error since I used %s format in char array without the '\0', but below is what I got.
char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };
printf("%c", testArray1[0]);
printf("%c", testArray1[1]);
printf("%c\n", testArray1[2]);
printf("%s\n", testArray1);
the result is
abc
abcqwer
thanks
CodePudding user response:
The format "%s"
expects that the corresponding argument points to a string: sequence of characters terminated by the zero character '\0'
.
printf("%s\n", testArray1);
As the array testArray1
does not contain a string then the call above has undefined behavior.
Instead you could write
printf("%.*s\n", 3,testArray1);
or
printf("%.3s\n", testArray1);
specifying exactly how many elements of the array you are going to output.
Pay attention to that in C instead of these declarations
char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };
you may write
char testArray1[3] = { "abc" };
char testArray2[] = { "qwer" };
or that is the same
char testArray1[3] = "abc";
char testArray2[] = "qwer";
In C the first declaration will be invalid.
CodePudding user response:
%s
indeed stop when encountered \0
, but testArray1
didn't have that \0
, so it keeps printing the following bytes in the memory.
And the compiler magically(actually intentionally) places the testArray2
next to testArray1
, the memory is like:
a b c q w e r \0
^ testArray1 starts here
^ testArray2 starts here
And the %s
will print all of those chars above until it meets a \0
.
You can validate that by:
printf("%d\n", testArray2 == testArray1 3);
// prints `1`(true)
As your question, there was no error because the a ... r \0
sequece in memory is owned by your process. Only the program is trying to access an address not owned by it, the OS will throw an error.
CodePudding user response:
Add zero at the end of first array:
char testArray1[] = { 'a','b','c', 0 };
Otherwise printf
continues with memory after 'c'
until zero byte and there is the second array.
PS: zero 0
is 100% identical to longer ASCII '\0'
.