You're correct:
"%08X"
, "%.8X"
and "%.08X"
are equivalent.
As for why - refer to this:
http://www.cplusplus.com/reference/cstdio/printf/
Hence:
In case 1, this one uses specifies the width:
Minimum number of characters to be printed. If the value to be printed
is shorter than this number, the result is padded with blank spaces.
The value is not truncated even if the result is larger.
Hence:
%08X
will print a minimum of 8 characters
and from this reference:
For integer specifiers (d, i, o, u, x, X): precision specifies the
minimum number of digits to be written. If the value to be written is
shorter than this number, the result is padded with leading zeros. The
value is not truncated even if the result is longer. A precision of 0
means that no character is written for the value 0. For a, A, e, E, f
and F specifiers: this is the number of digits to be printed after the
decimal point (by default, this is 6). For g and G specifiers: This is
the maximum number of significant digits to be printed. For s: this is
the maximum number of characters to be printed. By default all
characters are printed until the ending null character is encountered.
If the period is specified without an explicit value for precision, 0
is assumed.
%.8X
uses the precision specifier. As such, it too, will also print a minimum of 8 characters.
And lastly:
%.08X
will also print a minimum of 8 characters (again, because of the precision specifier). Why? Because 08
is interpreted as 8
- resulting in the same output as the previous. This may not seem to make sense for single digit precision specification outputs, but in a case like this:
%0.15X
It can matter.
These different formats exist to allow finer control of output (which in my opinion - is a carry over that resembles Fortran a lot).
However, as you've discovered, this overcompensation for finer control of precision allows you to get the same output - but with different flags.
UPDATE:
As hvd pointed out, which I had forgotten to mention: the X
specifier requires an unsigned value, so in this case your output is the same for %08X
and %.8X
(due to there being no sign). However, for something like: %08d
and %.8d
- it isn't as: one pads to 8 digits, the other to 8 characters, so they behave differently for negative values.