Why does printf
print a space instead of stopping when I use the NULL character from the ASCII table? This is what I mean:
printf("Hello%c, world", 0); //Hello , world
printf("Hello%c, world", '\0'); //Hello , world
Only when I put the escape character in the string itself printf
stops the string:
printf("Hello\0, world"); //Hello
I tried this on Windows 8, Windows 10 (using cygwin, MinGW, Netbeans, Code::Blocks), XUbuntu, it's all the same.
Where is the problem? I asked one of my friends, but he said that he has no such problem, that all three examples executed the same way.
printf("Hello\0, world");
uses its parameter as a C-string so it decodes it until it finds a NUL char, so it stops just after \0
, ignoring what follows.
printf("Hello%c, world", 0);
decodes its parameter (until it finds inside it a NUL char - i.e. after d
), in the meanwhile it finds a %c
, so it replaces it with the char given as parameter (whose ASCII code is NUL) and then send to the terminal a NUL char, and then continues.
Printf manual says:
These functions write the output under the control of a format string that specifies how subsequent arguments [...] are converted for output.
You are taking a dependency on a printf() implementation detail. The low-level terminal output function requires the length of the string as an argument. There are two ways for printf() to do this.
The somewhat obvious way is to first format the string, then use strlen(). That's the one you hoped for.
But that's inefficient because it requires a double pass across the string buffer and appending 0. The other way to do it is track the formatted string length while substituting the fields, simply incrementing it for every appended character. Since it continues past the %c, you'll now get the larger length that includes everything past %c. What the terminal function does with the embedded 0 is an implementation detail as well, given that it is not a printable character. Seeing it substituted with a space is not uncommon.
Sane way to go about this is to not rely on implementation details.
printf("Hello%c, world", 0); //Hello , world
printf("Hello%c, world", '\0'); //Hello , world
In both of these cases, you're trying to print out the character value corresponding to character code 0
, which is not a printable character. I haven't found chapter and verse on it, but I suspect the behavior of trying to print a nul character value is unspecified or maybe even undefined. Either way, I would not expect it to be treated as a string terminator in this case.
printf("Hello\0, world"); //Hello
In this case, the nul character is part of the string constant and is interpreted by the compiler as a string terminator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With