Home > Software design >  Trying to replicate printf behaviour about variadic paramenters
Trying to replicate printf behaviour about variadic paramenters

Time:01-28

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.

CodePudding user response:

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.

CodePudding user response:

Simply cat uses caret notation to display not printable characters. ^A represents 1 and ^Z represents 26. ^@ is 0 and

  • 27 - ^[,
  • 28 - ^\
  • 29 - ^]
  • 30 - ^^
  • 31 - ^_
  • 127 - ^?

CodePudding user response:

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".


I'm using memset to replace the character.

is unclear as there is no memset() in the question.

CodePudding user response:

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!

  • Related