The most important key letters are d, g (usually used as "lg"), and s.

code | type | format |
---|---|---|

d | int | decimal (base ten) number |

o | int | octal number (no leading '0' supplied in printf) |

x or X | int | hexadecimal number (no leading '0x' supplied in printf; accepted if present in scanf) (for printf, 'X' makes it use upper case for the digits ABCDEF) |

ld | long | decimal number ('l' can be applied to any of the above to change the type from 'int' to 'long') |

u | unsigned | decimal number |

lu | unsigned long | decimal number |

c | char [footnote] | single character |

s | char pointer | string |

f | float [footnote] | number with six digits of precision |

g | float [footnote] | number with up to six digits of precision |

e | float [footnote] | number with up to six digits of precision, scientific notation |

lf | double [footnote] | number with six digits of precision |

lg | double [footnote] | number with up to six digits of precision |

le | double [footnote] | number with up to six digits of precision, scientific notation |

Footnote: In printf(), the expression type promotions are expected -- in an
expression, char and short are converted to int, and float is converted to
double.
Thus %c
actually corresponds to a parameter of type int and %f and %g actually
correspond to parameters of type double. Thus in printf() there is no
difference between %f and %lf, or between %g and %lg.
However, in scanf() what is passed is a *pointer* to the variable so no
type promotions occur or are expected.
Thus %f and %lf are quite different in scanf, but the same in printf.

Personally, I used to use %lg routinely for doubles in both printf and scanf, but this is out of favour these days and indeed gcc will give you a warning message for using %lg in printf. The usual procedure these days is to use %g for double in printf and %lg for double in scanf. It doesn't matter which you use for printf because the printf library function treats them as synonymous, but it's crucial to get it right for scanf.

- a number is a field width
- '.' and a number is a "precision"
- Example: printf("%6.3f", 2.8) yields _2.800 (with a space before the '2')
- Note that that "6" includes the 3 decimal places and the 1 '.' -- 6 characters total. Thus 6-3-1 = 2 characters to the left of the decimal point.

- 0 (the digit zero) means pad with zeroes to field width (usually used only with integers)
- l (the letter) means "long", e.g. %ld to format a long int in decimal

int dollars = 2; int cents = 3; /* $2.03 */ printf(" ?? what goes here ?? ", dollars, cents);

If format is | then output is |
---|---|

"$%d.%d" | $2.3 |

"$%d.%2d" | $2. 3 (one space between "." and "3") |

"$%d.%02d" | $2.03 |

In "%02d", the 0 is *not* part of the field width.
It is a modifier character.
And when
you have a field width, you must write it such that it does not start
with a zero (and then you can prepend a zero as a modifier character if you
want that).