← Back to C series
🧱
Basic
printf format · scanf · safe input

Chapter 3 — Standard I/O

How C reads from the keyboard and writes to the screen. `printf` formats output; `scanf` parses input.

printfscanfformat specifier
Duration
1-2 hours
Level
📊 Beginner
Prerequisite
🎯 Basic 2
Outcome
Read input and format output cleanly

What you'll learn

  • 1Pick the right `printf` format specifier.
  • 2Use `scanf` to read int / double / multiple values.
  • 3Understand why `scanf` is risky and what to do instead.
  • 4Format numbers with width, precision, and padding.

Core Concepts

1) `printf` format specifiers

TypeSpecifierExample
int`%d``printf("%d", 42)`
double`%f``printf("%.2f", 3.14)`
char`%c``printf("%c", 'A')`
string`%s``printf("%s", "hi")`
pointer`%p``printf("%p", &x)`
size_t`%zu``printf("%zu", sizeof(int))`
hex`%x` / `%X``printf("%x", 255)` → ff
percent`%%``printf("100%%")`

2) Width and precision

c
printf("|%5d|\n", 42);     // |   42| width=5, right-aligned
printf("|%-5d|\n", 42);    // |42   | left-aligned
printf("|%.3f|\n", 3.14);  // |3.140| 3 decimal places
printf("|%8.2f|\n", 3.14); // |    3.14| width=8, precision=2

3) `scanf` basics

c
int n;
scanf("%d", &n);   // ← note the &

`scanf` needs **addresses** (pointers). Forgetting `&` is the classic crash.

4) Multiple values, one call

c
int a, b;
scanf("%d %d", &a, &b);  // whitespace = any spaces/newlines

5) Why `scanf` is dangerous

For strings, `scanf("%s", buf)` doesn't check length and overflows. Prefer `fgets` (chapter 4 — strings).

Examples

Example 1 — `ex01_printf.c`: format with width/precision

c
printf("%d\n", 42);
printf("%.3f\n", 3.14159);
printf("%-10s|%10s\n", "left", "right");

**Output**

text
42
3.142
left      |     right

Key: minus sign means left-align; `.N` is decimal places (or max chars for `%s`).

Example 2 — `ex02_scanf_int.c`: read a single integer

c
int n;
printf("Number? ");
scanf("%d", &n);
printf("Square = %d\n", n * n);

**Output**

text
Number? 7
Square = 49

Key: don't forget the `&` before `n`.

Example 3 — `ex03_scanf_multi.c`: read two integers

c
int a, b;
scanf("%d %d", &a, &b);
printf("Sum = %d\n", a + b);

**Output**

text
3 4
Sum = 7

Key: whitespace in the format matches any sequence of spaces/newlines.

Example 4 — `ex04_format.c`: floating-point precision

c
double pi = 3.14159265358979;
printf("%.2f\n", pi);
printf("%.5f\n", pi);
printf("%e\n", pi);

**Output**

text
3.14
3.14159
3.141593e+00

Key: `%e` is scientific notation; great for very large/small numbers.

Common mistakes

  1. **Missing `&` in `scanf`** — undefined behavior or instant crash.
  2. **Wrong specifier in `scanf`** — `%lf` for double in scanf, but `%f` in printf for double too.
  3. **`scanf("%s")` on user input** — buffer overflow waiting to happen.
  4. **No `\n` in printf** — output may not flush until program exits.

Recap

  • Match the format specifier to the value's type.
  • `scanf` wants addresses (`&var`); `printf` wants values.
  • For strings prefer `fgets`; for production use `strtol/strtod` over `scanf`.

Try it

bash
cd src
gcc -std=c11 -Wall -o ex01 ex01_printf.c && ./ex01
gcc -std=c11 -Wall -o ex02 ex02_scanf_int.c && ./ex02 <<< 7
gcc -std=c11 -Wall -o ex03 ex03_scanf_multi.c && ./ex03 <<< "3 4"
gcc -std=c11 -Wall -o ex04 ex04_format.c && ./ex04

💻 Examples

Compilable, runnable examples — see the output yourself.

ex01_printf.cformat with width/precision
CODE
#include <stdio.h>

int main(void) {
    int    n = 255;
    double x = 3.141592;

    printf("decimal: %d\n", n);
    printf("hex: %x\n", n);
    printf("octal: %o\n", n);
    printf("char: %c (code %d)\n", 'A', 'A');
    printf("string: %s\n", "Hello");
    printf("double default: %f\n", x);
    printf("double 2dp: %.2f\n", x);
    printf("scientific: %e\n", x);

    return 0;
}
▶ Output
42
3.142
left      |     right
ex02_scanf_int.cread a single integer
CODE
#include <stdio.h>

int main(void) {
    int n;

    printf("Enter int: ");
    if (scanf("%d", &n) != 1) {
        printf("Input error\n");
        return 1;
    }

    printf("input: %d\n", n);
    printf("double: %d\n", n * 2);
    return 0;
}
▶ Output
Number? 7
Square = 49
ex03_scanf_multi.cread two integers
CODE
#include <stdio.h>

int main(void) {
    int a, b;

    printf("Two ints separated : ");
    if (scanf("%d %d", &a, &b) != 2) {
        printf("Input error\n");
        return 1;
    }

    printf(":   %d\n", a + b);
    printf(":   %d\n", a - b);
    printf(":   %d\n", a * b);
    if (b != 0)
        printf(":   %d\n", a / b);

    return 0;
}
▶ Output
3 4
Sum = 7
ex04_format.cfloating-point precision
CODE
#include <stdio.h>

int main(void) {
    int   n = 42;
    double pi = 3.14159265;

    printf("[%5d]\n",   n);
    printf("[%-5d]\n",  n);
    printf("[%05d]\n",  n);
    printf("[%10.4f]\n", pi);
    printf("[%-10.4f]\n", pi);

    return 0;
}
▶ Output
3.14
3.14159
3.141593e+00

📝 Exercises

Try them yourself first, then open the solution to compare.

Exercise 1

Problem 1 (hw01.c)

Goal: Read a name and an age, then print a greeting.

Requirements
  • Filename: hw01.c
Sample I/O
Enter name and age: Alice 25
Hello, Alice! You are 25.
Toggle solution
SOLUTION
#include <stdio.h>

int main(void) {
    char name[64];
    int  age;

    printf("Name: ");
    scanf("%63s", name);

    printf("Age: ");
    scanf("%d", &age);

    printf("%s is %d years old.\n", name, age);
    return 0;
}
▶ Output
Enter name and age: Alice 25
Hello, Alice! You are 25.
Exercise 2

Problem 2 (hw02.c)

Goal: Read two ints and print their average with 2 decimal places.

Requirements
  • Filename: hw02.c
Toggle solution
SOLUTION
#include <stdio.h>

int main(void) {
    int a, b, c;

    printf(" Enter int: ");
    scanf("%d %d %d", &a, &b, &c);

    double avg = (a + b + c) / 3.0;
    printf("mean: %.2f\n", avg);
    return 0;
}
Exercise 3

Problem 3 (hw03.c)

Goal: Read a Celsius temperature and print the Fahrenheit equivalent.

Requirements
  • Filename: hw03.c
Toggle solution
SOLUTION
#include <stdio.h>

int main(void) {
    int seconds;

    printf("Seconds: ");
    scanf("%d", &seconds);

    int h = seconds / 3600;
    int m = (seconds % 3600) / 60;
    int s = seconds % 60;

    printf("%d:%d:%d\n", h, m, s);
    return 0;
}
Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub ↗