Why does printf(“%d\n”, printf(“%d\b”, a)) work this way

cescapingprintf

This is my C code, compiled with gcc.

#include<stdio.h>

int main() 
{ 
    int a=1; 
    switch(a)
    {
       int x=10;
       case 1:
           printf("%d\n",printf("%d\b",x));
           break;
       default:
           printf("%d\n",printf("%d\b",x));
    }
    return 0;
}

printf() is supposed to return the number of elements it printed successfully.
printf("%d\b", x) should have printed 10 by itself(since the \b takes the printing pointer one step behind (to the digit 0 in 10) and there is nothing to print after that.
So it should have just printed 10. That is 2 characters. Now the outer printf would display 2.
The output should have been 102.
The output I actually see is 2.

And in case of nested printfs is the printing pointer position remembered? I mean, if there is a \b in the inside printf , it would take the printing pointer one step behind. And when the control now goes to the outer printf, is that changed position remembered? Will it overwrite over that last character?

Best Answer

printf("%d\b",x)

prints the characters '1', '0' (because x==10) and \b. The \b is a backspace character; if you print to a terminal, it will print 10 and then move the cursor back one column.

A call to printf returns the number of characters it printed; in this case, the result is 3 (yes, '\b' counts as a character).

printf("%d\n",printf("%d\b",x));

The inner printf call works as I explained above, and returns 3. The outer printf call prints "3\n".

So the entire statement will print:

10\b3\n

The '\b' causes the 3 to be replace the 0 on the screen, so the final displayed result (when I run the program on my system) is:

13

If I pipe the output through cat -v, I get:

10^H3

where ^H represents the backspace character.

EDIT :

The question was just edited, and the modified program's behavior is quite different. The switch statement causes control to jump past the declaration int x = 10;, but into the scope in which x is declared. As a result, x is uninitialized when printf is called. This causes undefined behavior, and most likely garbage output (I just got -1217572876^H12). If x happens to be 0, I suppose you'd get 0^H2, which would look like 2.

Whatever you're trying to do, please find a better way to do it.