Input and output: printf and scanf

Introduction

printf writes, scanf reads. Both use format codes that start with % and must match the type of each value.

A program that only prints fixed values is not very useful. Reading input in C needs a little more care than in other languages, because you have to tell scanf both what to expect and where to put it.

How it works

Format codes

CodeTypescanfprintf example
%dint&nprintf("%d", n)
%f / %lfdouble%lf and &xprintf("%.2f", x)
%cchar" %c" and &cprintf("%c", c)
%sstringname (no &)printf("%s", name)
%lldlong long&bigprintf("%lld", big)

Note the trap: to read a double you need %lf, but to print one %f is enough.

Making output line up

A number between % and the letter sets the width; .2 sets the digits after the point:

#include <stdio.h>

int main(void) {
    printf("%-8s %5s %8s\n", "Item", "Qty", "Price");
    printf("%-8s %5d %8.2f\n", "Rice", 2, 65.5);
    printf("%-8s %5d %8.2f\n", "Oil", 1, 180.0);
    printf("%-8s %5d %8.2f\n", "Egg", 12, 12.25);
    return 0;
}
Open in compiler

Syntax

int n;
double x;
char c;
scanf("%d", &n);
scanf("%lf", &x);
scanf(" %c", &c);
printf("%5d|%-5d|%.2f\n", n, n, x);

Example

#include <stdio.h>

int main(void) {
    int a, b;
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
    int sum = a + b;
    printf("Sum = %d\n", sum);
    printf("Average = %.2f\n", sum / 2.0);
    return 0;
}

Input used: 12 31

Open in compiler

scanf("%d %d", &a, &b) reads two whole numbers from the input and stores them in a and b. The & gives scanf the address of each variable, so it can write into it. Without &, scanf would get the value instead of the address, which is a serious bug. StepVioz catches it and tells you to add &.

The input this example uses is shown under the code. You can change it in the Input box and run again.

Line by line

  1. int a, b; declares two variables that do not have values yet.
  2. The first printf shows a prompt, with no new line at the end.
  3. scanf("%d %d", &a, &b) reads two numbers and stores them at those addresses.
  4. sum adds them.
  5. sum / 2.0 is a double, because 2.0 is a double, so %.2f shows the true average.

Expected result

With this input:

12 31

it prints:

Enter two numbers: Sum = 43
Average = 21.50

In the real world

Command-line tools read input in just this way, and reading data correctly is often where bugs and security holes begin. Real programs also check that scanf read what they expected, using the number it returns.

Common mistakes

  • Forgetting & in scanf: scanf("%d", n).
  • Reading a double with %f: scanf needs %lf for a double.
  • Printing a double with %d (or an int with %f): the format must match the value.
  • To skip the newline left by the previous input before reading a char, put a space before it: scanf(" %c", &c).

Best practices

  • Keep format codes in step with the variables, one by one.
  • Check the value scanf returns when the input may be wrong.
  • Give each %s a maximum width, such as %49s.

Summary

scanf reads into the addresses it is given, and printf prints values. Format codes must match the types exactly, and widths and decimals control how neat the output looks.

Quick check

1. Which line correctly reads an int into n?
2. Which format reads a double with scanf?
3. What does printf("[%5d]", 42) print?

Key takeaways

  • scanf needs the address of each variable.
  • Read a double with %lf and print it with %f.
  • Put a space before %c to skip leftover whitespace.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.