Skip to content
Laviyx Learn

Try

C course menu

Input and Output in C: printf, scanf, fgets and Format Specifiers

Learn console input and output in C: printf format specifiers, width and precision, reading numbers with scanf and checking its return value, why scanf is risky for strings, reading lines safely with fgets, and putchar, getchar and puts.

Beginner8 min readUpdated
On this page

Most programs need to show results and read input. C does both with functions from stdio.h: printf for formatted output and scanf or fgets for input.

printf format specifiers#

SpecifierTypeExample output
%d or %iint42
%uunsigned int42
%ld, %lldlong, long long9000000000
%fdouble (and float)3.141593
%edouble in scientific notation3.141593e+00
%ccharA
%sstring (char *)Asha
%x, %Xhexadecimalff, FF
%ppointer addressan address
%zusize_t8
%%a literal percent sign%

The specifiers must match the argument types. A mismatch, such as passing a double for %d, is undefined behaviour; -Wall warns about it.

Width and precision#

C
#include <stdio.h>

int main(void) {
    double price = 3.14159;
    printf("[%.2f]\n", price);       /* 2 decimal places */
    printf("[%8.2f]\n", price);      /* width 8, right-aligned */
    printf("[%-8.2f]\n", price);     /* left-aligned */
    printf("[%05d]\n", 42);          /* pad with zeros */
    printf("[%10s]\n", "Asha");
    printf("[%-10s]|\n", "Asha");
    printf("%d%% done\n", 75);
    return 0;
}
Output
[3.14]
[    3.14]
[3.14    ]
[00042]
[      Asha]
[Asha      ]|
75% done

Width and alignment are handy for printing tables:

C
printf("%-10s %6s\n", "Item", "Price");
printf("%-10s %6.2f\n", "Notebook", 45.0);
printf("%-10s %6.2f\n", "Pen", 10.5);
Output
Item        Price
Notebook    45.00
Pen         10.50

Reading numbers with scanf#

scanf reads formatted input. It needs the address of each variable, written with &:

C
#include <stdio.h>

int main(void) {
    char name[20];
    int age;
    double weight;

    printf("Name: ");
    scanf("%19s", name);
    printf("Age: ");
    scanf("%d", &age);
    printf("Weight: ");
    scanf("%lf", &weight);

    printf("%s is %d years old and weighs %.1f kg\n", name, age, weight);
    return 0;
}
Output
Name: Asha
Age: 21
Weight: 64.5
Asha is 21 years old and weighs 64.5 kg
  • Use %lf (not %f) to read a double with scanf.
  • Arrays such as name do not need &; the array name already gives an address (Pointers and Arrays).
  • %19s limits the input to 19 characters, leaving room for the terminating '\0'. A plain %s can overflow the array, a serious security bug.
  • %s stops at the first space, so it cannot read "Asha Rao".

Check the return value#

scanf returns how many values it read successfully. Always check it:

C
#include <stdio.h>

int main(void) {
    int qty;
    printf("Quantity: ");
    if (scanf("%d", &qty) != 1) {
        printf("That is not a number.\n");
        return 1;
    }
    printf("You ordered %d\n", qty);
    return 0;
}
Output
Quantity: abc
That is not a number.

Without the check, qty would be used uninitialised.

Reading a whole line with fgets#

fgets reads a line, including spaces, and never writes past the buffer size you give it. It keeps the newline character, which you usually remove:

C
#include <stdio.h>
#include <string.h>

int main(void) {
    char full_name[50];
    printf("Full name: ");
    if (fgets(full_name, sizeof full_name, stdin) != NULL) {
        full_name[strcspn(full_name, "\n")] = '\0';   /* remove the newline */
        printf("Hello, %s!\n", full_name);
    }
    return 0;
}
Output
Full name: Asha Rao
Hello, Asha Rao!

A robust pattern for numbers is to read a line with fgets and then convert it with strtol (Type Conversion), which avoids leftover input problems that scanf causes when mixing numbers and lines.

Character and line output#

C
putchar('A');
putchar('\n');
puts("puts adds a newline automatically");
Output
A
puts adds a newline automatically

getchar() reads a single character and returns EOF at the end of the input.

Practice#

Practice exercise

Read two integers from the user and print their sum, difference and product in a neat table using width specifiers. Check that both numbers were read.

Show solution
C
#include <stdio.h>

int main(void) {
    int a, b;
    printf("Enter two numbers: ");
    if (scanf("%d %d", &a, &b) != 2) {
        printf("Please enter two whole numbers.\n");
        return 1;
    }
    printf("%-12s %5d\n", "Sum", a + b);
    printf("%-12s %5d\n", "Difference", a - b);
    printf("%-12s %5d\n", "Product", a * b);
    return 0;
}
Output
Enter two numbers: 12 5
Sum             17
Difference       7
Product         60

Key takeaway#

Finished this lesson?