Input and Output
Input and output are like a conversation between you and the computer — printf is the computer talking to you, scanf is you talking to the computer. Get the format right, or you'll be talking past each other.
printf Formatted Output
printf stands for "print formatted." Its first argument is a format string, followed by the values to output.
Basic Format Specifiers
| Specifier | Purpose | Example | Output |
|---|---|---|---|
%d |
Decimal integer | printf("%d", 42) |
42 |
%f |
Floating-point | printf("%f", 3.14) |
3.140000 |
%c |
Single character | printf("%c", 'A') |
A |
%s |
String | printf("%s", "hi") |
hi |
%x |
Hexadecimal | printf("%x", 255) |
ff |
%o |
Octal | printf("%o", 8) |
10 |
%p |
Pointer address | printf("%p", &a) |
Address value |
%% |
Literal percent sign | printf("100%%") |
100% |
#include <stdio.h>
int main(void) {
int age = 25;
float height = 175.5f;
char grade = 'A';
printf("Age: %d, Height: %.1f, Grade: %c\n", age, height, grade);
return 0;
}
Age: 25, Height: 175.5, Grade: A
Width and Alignment
You can insert numbers between % and the format specifier to control output width:
%5d: Minimum 5 characters wide, right-aligned%-5d: Minimum 5 characters wide, left-aligned%05d: Pad with zeros up to 5 digits
#include <stdio.h>
int main(void) {
int num = 42;
printf("[%5d]\n", num);
printf("[%-5d]\n", num);
printf("[%05d]\n", num);
printf("[%+5d]\n", num);
return 0;
}
[ 42]
[42 ]
[00042]
[ +42]
Floating-Point Precision
%.2f: 2 digits after the decimal point%8.2f: Total width at least 8 characters, 2 digits after the decimal point%-8.2f: Left-aligned version
#include <stdio.h>
int main(void) {
double pi = 3.14159265358979;
printf("Default: %f\n", pi);
printf("2 places: %.2f\n", pi);
printf("6 places: %.6f\n", pi);
printf("8.2: %8.2f\n", pi);
return 0;
}
Default: 3.141593
2 places: 3.14
6 places: 3.141593
8.2: 3.14
%f defaults to 6 decimal places. Use %.0f to hide the decimal portion entirely.
scanf Reading Input
scanf stands for "scan formatted." It reads data from standard input according to the format string and stores it in variables.
Basic Usage
#include <stdio.h>
int main(void) {
int age;
float score;
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your score: ");
scanf("%f", &score);
printf("Age: %d, Score: %.1f\n", age, score);
return 0;
}
Enter your age: 20
Enter your score: 92.5
Age: 20, Score: 92.5
& (the address-of operator), telling scanf "store the value at this address." Forgetting & is the most common beginner mistake — the program won't error out but will crash.
Reading Multiple Values
#include <stdio.h>
int main(void) {
int a, b, c;
printf("Enter three integers (separated by spaces): ");
scanf("%d %d %d", &a, &b, &c);
printf("You entered: %d, %d, %d\n", a, b, c);
return 0;
}
Enter three integers (separated by spaces): 10 20 30
You entered: 10, 20, 30
By default, scanf uses whitespace (spaces, newlines, tabs) to separate different values.
Reading Characters and Strings
#include <stdio.h>
int main(void) {
char ch;
char name[20];
printf("Enter a character: ");
scanf(" %c", &ch);
printf("Enter your name (no spaces): ");
scanf("%s", name);
printf("Character: %c, Name: %s\n", ch, name);
return 0;
}
%c (" %c") skips whitespace characters, otherwise it will read the leftover newline from previous input. %s reads a string but stops at whitespace. name is an array name, which is already an address, so no & is needed.
scanf's Return Value
scanf returns the number of successfully read variables. This feature can be used to validate input:
#include <stdio.h>
int main(void) {
int num;
printf("Enter an integer: ");
int result = scanf("%d", &num);
if (result == 1) {
printf("Successfully read: %d\n", num);
} else {
printf("Invalid input!\n");
}
return 0;
}
Enter an integer: abc
Invalid input!
getchar and putchar
getchar() reads a single character from the keyboard, and putchar() outputs a single character to the screen. They're simpler and more efficient than scanf("%c") and printf("%c").
#include <stdio.h>
int main(void) {
char ch;
printf("Enter a character: ");
ch = getchar();
printf("You entered: ");
putchar(ch);
putchar('\n');
return 0;
}
Enter a character: X
You entered: X
Reading an Entire Line
getchar() combined with a loop can read an entire line until a newline is encountered:
#include <stdio.h>
int main(void) {
char ch;
printf("Enter a line of text: ");
while ((ch = getchar()) != '\n') {
putchar(ch);
}
putchar('\n');
return 0;
}
Enter a line of text: Hello World!
Hello World!
while ((ch = getchar()) != '\n') is a classic idiom: first read a character into ch, then check if it's a newline. Note that the outer parentheses around the assignment are mandatory.
Buffer Issues
C's standard input uses line buffering: the entire line of data is only delivered to the buffer for the program to read after the user presses Enter. This can cause some confusing problems.
Problem: scanf %c Reads a Leftover Newline
#include <stdio.h>
int main(void) {
int num;
char ch;
printf("Enter an integer: ");
scanf("%d", &num);
printf("Enter a character: ");
scanf("%c", &ch);
printf("Integer=%d, Character=%d\n", num, ch);
return 0;
}
Enter an integer: 42
Enter a character: Integer=42, Character=10
After typing 42 and pressing Enter, the buffer contains 42\n. scanf("%d") reads 42, and scanf("%c") immediately reads that leftover \n (ASCII code 10), without waiting for you to type a character.
Solutions
Solution 1: Add a space before %c (recommended)
scanf(" %c", &ch);
The space skips all whitespace characters (including newlines, spaces, and tabs).
Solution 2: Use getchar() to absorb the leftover
scanf("%d", &num);
getchar();
scanf("%c", &ch);
Solution 3: Clear the input buffer
int c;
while ((c = getchar()) != '\n' && c != EOF) {}
fflush(stdin) to clear the input buffer — it's undefined behavior in standard C. Some compilers support it, but it's not portable.
Example
Write a program that reads both an integer and a character, properly handling buffer leftovers:
#include <stdio.h>
int main(void) {
int age;
char gender;
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your gender (M/F): ");
scanf(" %c", &gender);
printf("Age: %d, Gender: %c\n", age, gender);
return 0;
}
Enter your age: 25
Enter your gender (M/F): M
Age: 25, Gender: M
Example
Use getchar() to read character by character and count the number of letters and digits in a line:
#include <stdio.h>
int main(void) {
char ch;
int letters = 0;
int digits = 0;
printf("Enter a line of text: ");
while ((ch = getchar()) != '\n') {
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {
letters++;
} else if (ch >= '0' && ch <= '9') {
digits++;
}
}
printf("Letters: %d, Digits: %d\n", letters, digits);
return 0;
}
Enter a line of text: Hello 2024!
Letters: 5, Digits: 4
puts and fputs
puts() outputs a string and automatically appends a newline. It's simpler than printf and ideal for plain text output:
#include <stdio.h>
int main(void) {
puts("Hello, World!");
puts("Auto newline, no need for \\n");
return 0;
}
Hello, World!
Auto newline, no need for \n
puts() is more efficient than printf("%s\n", ...) because it doesn't need to parse a format string. When you don't need formatting, prefer puts.
❓ FAQ
& in front?& takes the variable's address. Only array names don't need it, because an array name is already the address of its first element.scanf(" %c", &ch) to skip whitespace.%d lowercase corresponds to int; uppercase %D is non-standard. But %x prints lowercase hex (abcdef) while %X prints uppercase (ABCDEF) — this is valid.scanf("%s") stops at whitespace. Use fgets(name, sizeof(name), stdin) to read an entire line — it supports spaces and is safer.📖 Summary
printfuses format specifiers to control output: width, precision, alignment, paddingscanfrequires&before variables; add a space before%cto avoid reading leftover newlinesgetchar/putcharare efficient choices for single-character I/O- Line buffering causes leftover data issues between scanf and getchar calls
- scanf's return value can be used to validate whether input was successful
📝 Exercises
- Write a program that reads a circle's radius and outputs its area and circumference using
printf's%.2fformat. - Write a program that uses
getchar()to read a line of input and counts how many uppercase and lowercase letters it contains. - Write a program that reads an integer and outputs it in decimal (
%d), hexadecimal (%x), and octal (%o) formats.



