Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

What is the difference between conversion specifiers %i and %d in formatted IO functions (*printf / *scanf)

Ask Question

They are the same when used for output, e.g. with printf .

However, these are different when used as input specifier e.g. with scanf , where %d scans an integer as a signed decimal number, but %i defaults to decimal but also allows hexadecimal (if preceded by 0x ) and octal (if preceded by 0 ).

So 033 would be 27 with %i but 33 with %d .

Expecting an int with possible zero-padding in sscanf seems to me to be the most reasonable default behavior. If you're not expecting Octal, that could cause subtle bugs. So this suggests that %d is a good specifier to use when you have to choose one arbitrarily, unless you explicitly want to read octal and/or hex. Eliot Sep 6, 2013 at 22:28 Ah! That makes sense! Now that I know what to look for, this can also be seen in the documentation for printf and scanf . Gabriel Staples Nov 8, 2018 at 19:49 The octal thing bit me once in Javascript. (some numeric value from the db was initially in string form with leading zeros). Man that was a bugger to track down. Scott Smith Jan 13, 2021 at 19:46

These are identical for printf but different for scanf . For printf , both %d and %i designate a signed decimal integer. For scanf , %d and %i also means a signed integer but %i inteprets the input as a hexadecimal number if preceded by 0x and octal if preceded by 0 and otherwise interprets the input as decimal.

There is no difference between the %i and %d format specifiers for printf . We can see this by going to the draft C99 standard section 7.19.6.1 The fprintf function which also covers printf with respect to format specifiers and it says in paragraph 8 :

The conversion specifiers and their meanings are:

and includes the following bullet:

d,i     The int argument is converted to signed decimal in the style
        [−]dddd. The precision specifies the minimum number of digits to
        appear; if the value being converted can be represented in fewer
        digits, it is expanded with leading zeros. The default precision is
        1. The result of converting a zero value with a precision of zero is
        no characters.

On the other hand for scanf there is a difference, %d assume base 10 while %i auto detects the base. We can see this by going to section 7.19.6.2 The fscanf function which covers scanf with respect to format specifier, in paragraph 12 it says:

The conversion specifiers and their meanings are:

and includes the following:

d     Matches an optionally signed decimal integer, whose format is the
      same as expected for the subject sequence of the strtol function with
      the value 10 for the base argument. The corresponding argument shall
      be a pointer to signed integer.
i     Matches an optionally signed integer, whose format is the same as
      expected for the subject sequence of the strtol function with the
      value 0 for the base argument. The corresponding argument shall be a
      pointer to signed integer.