Reputation: 43
I'm trying to replicate some printf
functionality for education purposes, but I've encountered some printf
behavior that I'm unable to understand. I'll try explaining with a simple example:
have this call:
printf(" %c %c %c", 0, 1, 2); // yes, parameters are ints not chars.
The output seems normal, only 3 spaces, numbers are ignored.
But taking printf
output to a file, then using "cat -e file" does this:
^@ ^A ^B
^@ for 0, ^A for 1, ^B for 2 and so on.
Here is my question, what are those symbols? How they relate to the values?
Also my own printf
, does this as well except for the 0 which is treated as a '\0' char...I need to mimic printf
exactly so I need to understand what is going on there...
I've searched about those symbols, but can't find anything. They are not memory garbage because the results are always same.
Upvotes: 2
Views: 102
Reputation: 67820
Simply cat uses caret notation to display not printable characters. ^A
represents 1 and ^Z
represents 26. ^@
is 0 and
^[
^\
^]
^^
^_
^?
Upvotes: 4
Reputation: 43
Got it solved. Thanks to the explanations here, i realized that even i was printing the resulting string with write() i was using a pointer to iterate it so never gave a chance to actually pass over that null character.
write(STDOUT_FD, delta, d_length);
Then write() does the job correcty:
make test > check.txt && cat -e check.txt
own: ^@ ^A ^B$
lib: ^@ ^A ^B$
Also now i know about the caret notation, thanks everyone!
Upvotes: 0
Reputation: 154075
What i meant is why
printf
prints ^@ while im getting '\0'(?)
printf("%c", 0);
prints the null character to stdout
. What you see when viewing the output of stdout
is not part of stdout
, but an implementation detail of the shell/terminal program. Print the return value of printf()
to get its understanding of how many characters it printed. Perhaps on stderr
to separate it from stdout
.
int count = printf(" %c %c %c", 0, 1, 2);
fprintf(stderr, "<%d>\n", count);
The output seems normal, only 3 spaces, numbers are ignored.
"Seems" deserves more detail. How was only 3 determined?
But taking printf output to a file, ...
What was the length of the file? 6?
... then using "cat -e file" does this:
Refer to @dbush good answer as to why you now see " ^@ ^A ^B".
is unclear as there is no memset()
in the question.
Upvotes: 1
Reputation: 224437
The -e
option to cat
tells it to use a particular notation for printing non-printable characters. ^@
represents the value 0, ^A
represents the value 1, and ^B
represents the value 2. Those are exactly the values you gave.
Upvotes: 4