Printing Variables
At the end of each day the logger prints a summary line: how many readings, the average, the unit. printf builds that line from a template and a list of values. It is fast and flexible, but it trusts you completely: it cannot see the types of your values, so if the template and the values disagree, the output is garbage or worse.
The rule
Every % in printf needs one matching value of the matching type.
The first argument is the format string. Each conversion specifier, starting with %, is replaced by the next argument, left to right:
int count = 3;
double avg = 21.466;
char unit = 'C';
printf("%d readings, average %.1f %c\n", count, avg, unit);
/* prints: 3 readings, average 21.5 C */The specifiers you will use most:
| Specifier | Type | Example output |
|---|---|---|
%d |
int |
42 |
%u |
unsigned int |
42 |
%ld / %lld |
long / long long |
5256000 |
%zu |
size_t (from sizeof) |
96 |
%f |
double (a float is promoted to double) |
21.466000 |
%c |
a character | C |
%s |
a string | ready |
%x |
unsigned int in hexadecimal |
2a |
%% |
a literal percent sign | % |
Between % and the letter you can add a width and a precision:
%5dpads the number to at least 5 characters, right-aligned;%-5dleft-aligns.%.1fshows one digit after the decimal point, rounding the value.%8.2fdoes both.
If a specifier does not match its argument's type, for example %d given a double, the behaviour is undefined. -Wall turns on GCC's and Clang's format checks, which catch most mismatches at compile time.
The shortcut
Pair them up. Draw an imaginary line from each % to its argument, left to right, and check two things: the counts match, and each type fits its letter.
Count
%d,%.1f,%c: three specifiers.count,avg,unit: three arguments. Good.
Drills
Answer fast — trust the rule.
Which specifier prints a size_t, such as the result of sizeof hourly?
What does printf("%.1f", 19.27); print?
What does printf("[%4d]", 42); print?
What does printf("%d%%\n", 75); print?
What does printf("%d\n", 21.5); do?
Remember
- Every % in printf needs one matching value of the matching type.
- Shortcut: pair each
%with its argument, left to right; check the count and the types. - Trap: a mismatch is undefined behaviour, not a conversion. Build with
-Wallto catch it.
