Because the standard says so:
ISO C standard 18.104.22.168 Section 4
Each conversion specification is introduced by the character %. After the %, the following
appear in sequence:
— Zero or more flags (in any order) that modify the meaning of the conversion
— An optional minimum field width. If the converted value has fewer characters than the
field width, it is padded with spaces (by default) on the left (or right, if the left
adjustment flag, described later, has been given) to the field width. The field width
takes the form of an asterisk * (described later) or a decimal integer.232)
— An optional precision that gives the minimum number of digits to appear for the d, i,
o, u, x, and X conversions, the number of digits to appear after the decimal-point
character for a, A, e, E, f, and F conversions, the maximum number of significant
digits for the g and G conversions, or the maximum number of bytes to be written for
s conversions. The precision takes the form of a period (.) followed either by an
asterisk * (described later) or by an optional decimal integer; if only the period is
specified, the precision is taken as zero. If a precision appears with any other
conversion specifier, the behavior is undefined.
— An optional length modifier that specifies the size of the argument.
— Aconversion specifier character that specifies the type of conversion to be applied.
ISO C standard 22.214.171.124 Section 6
The flag characters and their meanings are:
- The result of the conversion is left-justified within the field. (It is right-justified if
this flag is not specified.)
+ The result of a signed conversion always begins with a plus or minus sign. (It
begins with a sign only when a negative value is converted if this flag is not
space If the first character of a signed conversion is not a sign, or if a signed conversion
results in no characters, a space is prefixed to the result. If the space and + flags
both appear, the space flag is ignored.
# The result is converted to an ‘‘alternative form’’. For o conversion, it increases
the precision, if and only if necessary, to force the first digit of the result to be a
zero (if the value and precision are both 0, a single 0 is printed). For x (or X)
conversion, a nonzero result has 0x (or 0X) prefixed to it. For a, A, e, E, f, F, g,
and G conversions, the result of converting a floating-point number always
contains a decimal-point character, even if no digits follow it. (Normally, a
decimal-point character appears in the result of these conversions only if a digit
follows it.) For g and G conversions, trailing zeros are not removed from the
result. For other conversions, the behavior is undefined.
0 For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversions, leading zeros
(following any indication of sign or base) are used to pad to the field width rather
than performing space padding, except when converting an infinity or NaN. If the
0 and - flags both appear, the 0 flag is ignored. For d, i, o, u, x, and X
conversions, if a precision is specified, the 0 flag is ignored. For other
conversions, the behavior is undefined.