After the % appear:

• optional flags
• an optional field width
• an optional precision
• an optional "h", "l", or "L"
• a character specifying the conversion type

The flags are:

• minus:  left justify the conversion within the field width, instead of right justify;
• plus:  any signed conversion will begin with a plus or minus sign;
• space:  any signed conversion which does not begin with a sign will be prefixed with a space; this is ignored if the plus flag also appears;
• hash:  for "o" conversion, ensure that the first digit is a zero; for "x" conversion, a non-zero result will begin with "0x"; for "X" conversion, a non-zero result will begin with "0X"; for floating-point conversions, there will always be a decimal point even if no digits follow it; for "g" and "G" conversion, trailing zeroes are retained; hash may not appear on any other conversions;
• zero:  explained on page 133.

The field width is an asterisk or a decimal integer. If the converted value has fewer characters that the field width, it is padded to the width (unless altered by the flags, the padding is with spaces on the left). The field width cannot reduce the width of the converted value. Note that a zero at the start of the width is the "0" flag; it does not mean that the width is in octal.

The precision is a dot followed by an asterisk, a decimal integer, or nothing (equivalent to zero). It can only appear with certain conversions, and its meaning varies:

• d, i, o, u, x, X: the minimum number of digits to appear
• e, E, f: the number of digits after the decimal point
• g, G: the maximum number of signficant digits
• s: the maximum number of characters to be taken from the string
It must not appear with any other conversion.

If the width, precision, or both, is an asterisk, the actual value is taken from an int argument to the `fprintf()` function. The arguments are always in the order:

• width if an asterisk
• precision if an asterisk
• actual value to be converted
A negative width means add the "-" flag and use the absolute value; a negative precision means that the precision should be treated as if omitted.

The optional letters may appear as follows:

• h with d, i, o, u, x, X: the argument value (which is int or unsigned int) will be converted to short or unsigned short before printing;
• h with n: the argument is a (short *) rather than a (int *);
• l with d, i, o, u, x, X: the argument is long or unsigned long
• l with n: the argument is a (long *) rather than a (int *);
• L with e, E, f, g, G: the argument is a long double rather than a double.
These letters may not appear with any other conversion.