printf formatter Ready
Flags
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

The parts of a conversion specification

printf copies its format string to the screen. Each % starts a conversion specification that is replaced by the next argument. Between % and the conversion letter you can add flags, a minimum width and a precision — in exactly this order.

%  [flags]  [width]  [.precision]  conversion

%d       42          →  42
%5d      42          →     42
%-5d|    42          →  42   |
%05d     42          →  00042
%+d      42          →  +42
%.2f     3.14159     →  3.14
%8.2f    3.14159     →      3.14
%e       12345.678   →  1.234568e+04
Conversion specifiers
Specifier Argument type Prints Example Output
%d %i int signed decimal printf("%d", -42) -42
%u unsigned int unsigned decimal printf("%u", 42u) 42
%o unsigned int octal printf("%o", 8) 10
%x %X unsigned int hexadecimal printf("%x %X", 255, 255) ff FF
%c int (a char) one character printf("%c", 'A') A
%s string (char *) characters up to \0 printf("%s", "Hi") Hi
%f double (float too) fixed point, 6 decimals printf("%f", 2.5) 2.500000
%e %E double scientific notation printf("%e", 1234.5) 1.234500e+03
%g %G double shorter of %f / %e printf("%g", 0.0001) 0.0001
%ld %lld long / long long signed decimal printf("%lld", 10000000000LL) 10000000000
%lu %llu unsigned long (long) unsigned decimal printf("%lu", 42UL) 42
%zu size_t (from sizeof) unsigned decimal printf("%zu", sizeof(int)) 4
%p pointer an address printf("%p", (void *) &x) 0x7ffe…
%% — a percent sign printf("100%%") 100%

Width and precision

  1. Width is a MINIMUM: %6d prints 42 as " 42" (right-aligned). Longer values are never cut.
  2. For %f / %e precision is the number of decimals: %.2f rounds 3.14159 to 3.14.
  3. For %g precision is the number of significant digits.
  4. For %d precision is the minimum number of digits: %.4d prints 0042.
  5. For %s precision is the maximum number of characters: %.3s prints Hel.

The flags

  1. - left-aligns inside the width: "%-6d|" prints "42 |".
  2. + always prints a sign: %+d prints +42.
  3. space puts a space where a + would be: % d prints " 42".
  4. 0 pads numbers with zeros instead of spaces: %05d prints 00042 (ignored with -).
  5. # alternate form: %#x prints 0xff, %#o prints 010, %#.0f keeps the point.

Rules that prevent bugs

  1. Every % needs exactly one argument of the matching type, in the same order.
  2. printf does not convert types: %f with an int (or %d with a double) prints garbage.
  3. Compile with -Wall: gcc then checks the format string against the arguments.
  4. To print a % sign write %%.
  5. printf returns the number of characters it printed.
Walkthrough

A neat bill with printf

Every line, explained.

1 #include <stdio.h>
2
3 int main(void)
4 {
5 int qty = 3;
6 double price = 49.5;
7 printf("%-10s%5s%10s\n", "Item", "Qty", "Amount"); %-10s left-aligns "Item" in 10 columns; %5s and %10s right-align the other headings.
8 printf("%-10s%5d%10.2f\n", "Notebook", qty, qty * price); The same widths line the numbers up under their headings: Notebook, then 3 in the Qty column, then 148.50 in the Amount column.
9 printf("%-10s%5s%10.2f\n", "GST 18%", "", qty * price * 0.18); "GST 18%" is a %s ARGUMENT, so its % is printed as it is. 26.73 lands in the Amount column.
10 printf("%+d%% change\n", 12); %+d shows the sign, %% prints a percent sign: +12% change
11 printf("Code: %05d Hex: %#x\n", 42, 255); Zero padding and the 0x prefix: Code: 00042 Hex: 0xff
12 return 0;
13 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

A specifier that does not match

✗ Wrong
double avg = 84.5;
printf("%d", avg);   // garbage
✓ Right
double avg = 84.5;
printf("%.1f", avg);  // 84.5

printf trusts the format string. %d with a double prints a meaningless number — gcc -Wall warns about it.

Fewer arguments than specifiers

✗ Wrong
printf("%d + %d = %d\n", a, b);
✓ Right
printf("%d + %d = %d\n", a, b, a + b);

The third %d reads whatever is in memory. Count the % signs and the arguments.

Printing a percent sign

✗ Wrong
printf("Score: 95%\n");
✓ Right
printf("Score: 95%%\n");

A single % starts a conversion (%\n is not valid). Write %% for one % sign.

Printing a float with %d

✗ Wrong
float r = 2.5f;
printf("%d", r);
✓ Right
float r = 2.5f;
printf("%f", r);   // %lf also works

A float passed to printf becomes a double, so %f prints both float and double. (In scanf it is different: %f for float, %lf for double.)

Expecting width to cut text

✗ Wrong
printf("%3d", 12345);   // expects 345
✓ Right
printf("%3d", 12345);   // prints 12345

Width is only a minimum. To cut a string use precision: %.3s.

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

What does printf("[%5d]", 42); print?

Question 2

What does printf("%.2f", 2.678); print?

Question 3

Which specifier prints 255 as ff?

Question 4

How do you print 100% with printf?

Question 5

What does printf("[%-4d]", 7); print?

Assessment

Output with printf quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.