cprintfscanfformat-specifiersconversion-specifier

Differing output with printf using %d and %i


I found questions about %i and %d on here, but all of them seemed to claim that they were the same in printf.
Compiler: Apple clang version 12.0.5 (clang-1205.0.22.9)
Note: 15 is 017 in octal and 0xf in hexidecimal.

I was previously under the impression that %d and %i only differed when used during scanf and not printf. Is this implementation defined behavior? Additionally I thought the number would have been converted and stored prior to the call to scanf.

Output:
scanf using %i: 017 017 0xf 0xf //user input
%i: 15, %d: 15, %i: 15, %d: 15

scanf using %d: 010 010 0xf 0xf //user input
%i: 10, %d: 10, %i: 0, %d: 15 //They all make sense to me except these last two

Code:

int a, b, c, d;     
                        
printf("scanf using %%i: ");    
scanf("%i %i %i %i", &a, &b, &c, &d);    
printf("%%i: %i, %%d: %d, %%i: %i, %%d: %d\n\n",a,b,c,d);    
                        
printf("scanf using %%d: ");    
scanf("%d %d %d %d", &a, &b, &c, &d);    
printf("%%i: %i, %%d: %d, %%i: %i, %%d: %d\n\n",a,b,c,d);

Solution

  • scanf("%d %d %d %d", &a, &b, &c, &d); scans 010 010 0 from the input and assigns: 10 to a, 10 to b and 0 to c.

    Then xf 0xf is left in the input. Because character 'x' is invalid for a number %d for &d, so scanf fails the scanning and d is left not assigned and scanf() returns 3 rather than 4 to let you know it failed to read 4 values.

    So c has the value of 0, and d has the previous value of 15.

    Is this implementation defined behavior?

    No, it is defined.