C Notes
Complete guide to scanf() in C: reading integers, floats, characters, and strings. Understand the address-of operator, buffer issues, return values, and common pitfalls with practical examples.
The scanf() function reads formatted input from the standard input (keyboard). While printf() sends data out, scanf() brings data in. It's the counterpart to printf() and uses similar format specifiers, but with some critical differences that trip up beginners — particularly the requirement for the address-of operator (&) and the notorious newline buffer problem.
Basic Syntax
int scanf(const char *format, ...);scanf() reads input according to the format string and stores values at the memory addresses provided. It returns the number of items successfully read.
#include <stdio.h>
int main() {
int age;
float height;
char grade;
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your height (in meters): ");
scanf("%f", &height);
printf("Enter your grade: ");
scanf(" %c", &grade); // Note the space before %c
printf("\nAge: %d, Height: %.2f m, Grade: %c\n", age, height, grade);
return 0;
}Enter your age: 20 Enter your height (in meters): 1.75 Enter your grade: A Age: 20, Height: 1.75 m, Grade: A
The Address-of Operator (&)
This is the most common source of errors for beginners. scanf() needs the memory address of where to store the input, not the variable's value:
Enter a number: 42 You entered: 42 Enter your name: Alice Hello, Alice!
Reading Different Data Types
Enter an integer: 42 Enter a float: 3.14 Enter a double: 2.718281828 Enter a character: X Enter a word: Hello Enter a long long: 9876543210 Results: int: 42 float: 3.140000 double: 2.718282 char: X string: Hello long long: 9876543210
Important: %f vs %lf in scanf
Unlike printf() where %f works for both float and double, in scanf() you must use %lf for doubles:
| Type | scanf specifier | printf specifier |
|---|---|---|
| float | %f | %f |
| double | %lf | %f or %lf |
| long double | %Lf | %Lf |
Reading Multiple Values
Enter date (DD MM YYYY): 15 06 2024 Date: 15/06/2024 Enter date (DD/MM/YYYY): 25/12/2024 Date: 25/12/2024 Enter name age gpa: John 21 3.8 John is 21 years old with GPA 3.8
The Newline Problem
The most notorious issue with scanf() — when you read a number followed by a character, the leftover \n from pressing Enter gets consumed by %c:
#include <stdio.h>
int main() {
int num;
char ch;
printf("Enter a number: ");
scanf("%d", &num); // Reads number, leaves '\n' in buffer
printf("Enter a character: ");
scanf("%c", &ch); // BUG! Reads the leftover '\n'
printf("Number: %d, Char: '%c' (ASCII: %d)\n", num, ch, ch);
return 0;
}Enter a number: 42 Enter a character: Number: 42, Char: ' ' (ASCII: 10)
Solutions to the Newline Problem
#include <stdio.h>
int main() {
int num;
char ch;
printf("Enter a number: ");
scanf("%d", &num);
// Solution 1: Space before %c (skips all whitespace)
printf("Enter a character: ");
scanf(" %c", &ch); // Leading space consumes whitespace
printf("Char: '%c'\n", ch);
// Solution 2: getchar() to consume the newline
// getchar();
// scanf("%c", &ch);
// Solution 3: Use %*c to discard one character
// scanf("%d%*c", &num);
return 0;
}Enter a number: 42 Enter a character: A Char: 'A'
Return Value of scanf()
scanf() returns the number of items successfully read. This is crucial for input validation:
#include <stdio.h>
int main() {
int num;
int result;
printf("Enter a number: ");
result = scanf("%d", &num);
if (result == 1) {
printf("Successfully read: %d\n", num);
} else if (result == 0) {
printf("Input was not a valid integer\n");
} else { // result == EOF
printf("End of input or error\n");
}
// Reading multiple values
int a, b;
printf("Enter two numbers: ");
result = scanf("%d %d", &a, &b);
printf("scanf returned: %d\n", result);
if (result == 2) {
printf("Both read: %d and %d\n", a, b);
} else {
printf("Failed to read both numbers\n");
}
return 0;
}Enter a number: 42 Successfully read: 42 Enter two numbers: 10 20 scanf returned: 2 Both read: 10 and 20
Reading Strings with scanf()
%s reads a single word (stops at whitespace). It cannot read full lines:
Enter a sentence: Hello World scanf read: "Hello" Enter a full line: How are you today? fgets read: "How are you today? " Enter a word (max 9 chars): Programming Limited read: "Programmi"
Scansets: Advanced Input Patterns
You can specify which characters to accept or reject:
Enter a line: Hello World 123 Read: "Hello World 123" Enter digits: 12345abc Digits: "12345" Enter letters: Hello123 Letters: "Hello"
Common Pitfalls and Best Practices
1. Buffer Overflow Prevention
2. Input Validation Loop
#include <stdio.h>
int main() {
int num;
int result;
do {
printf("Enter a positive integer: ");
result = scanf("%d", &num);
if (result != 1) {
printf("Invalid input! Please enter a number.\n");
while (getchar() != '\n'); // Clear invalid input
num = -1; // Force loop to continue
} else if (num <= 0) {
printf("Must be positive!\n");
}
} while (num <= 0);
printf("You entered: %d\n", num);
return 0;
}Enter a positive integer: abc Invalid input! Please enter a number. Enter a positive integer: -5 Must be positive! Enter a positive integer: 42 You entered: 42
scanf() vs fgets() + sscanf()
For production code, many programmers prefer fgets() + sscanf() over direct scanf():
Enter a number: 42 Valid number: 42
Interview Questions
Q1: Why does scanf() need the & (address-of) operator?
scanf() needs to modify the variable's value, so it requires the memory address where the value should be stored. Without &, you'd be passing the variable's current value (which would be interpreted as a memory address), causing undefined behavior. Arrays don't need & because array names already decay to pointers.
Q2: What is the difference between %f and %lf in scanf()?
In scanf(), %f reads a float and %lf reads a double. This distinction is critical — using %f for a double variable will only write 4 bytes instead of 8, causing data corruption. In printf(), both work for double due to automatic float-to-double promotion.
Q3: How do you handle the newline left in the buffer after scanf("%d")?
Three common solutions: (1) Add a space before the next %c: scanf(" %c", &ch), which skips whitespace; (2) Call getchar() to consume the newline; (3) Use %*c to discard one character. The space-before-%c approach is the most reliable.
Q4: What does scanf() return and why is it important?
scanf() returns the number of items successfully read and assigned. It returns EOF on input failure. Checking the return value is essential for input validation — if scanf("%d", &x) returns 0, the user entered non-numeric data and x was not modified.
Q5: Why is scanf("%s") dangerous for reading strings?
scanf("%s") has no built-in length limit — if the user enters more characters than the buffer can hold, it causes buffer overflow (a security vulnerability). Always use a width specifier: scanf("%49s", str) for a 50-byte buffer, or better yet, use fgets().
Summary
scanf()reads formatted input and stores values at given memory addresses- Always use
&with scalar variables; arrays don't need& - Use
%lffor doubles in scanf (not%f) - The newline buffer problem is solved with a space before
%c:scanf(" %c", &ch) - Always check scanf's return value for input validation
- Limit string reads with width specifier:
%49sprevents buffer overflow - For robust input handling, prefer
fgets()+sscanf()over directscanf()
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for scanf() Function in C Programming.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, input, output, scanf, function, scanf() function in c programming
Related C Programming Topics