Input/Output in C
Make your programs interactive! Learn to display output with printf() and read user input with scanf(). Essential for every C program.
Track Your Progress
Sign in to save your learning progress
What You Will Learn
- ✓Display text and numbers with printf()
- ✓Use format specifiers (%d, %f, %c, %s)
- ✓Read user input safely with scanf()
- ✓Format output (decimals, width, alignment)
01What is Input/Output in C?
Simple Definition
Input/Output (I/O) is how your C program communicates with the user:
INPUT
Getting data from keyboard
scanf()
OUTPUT
Displaying data on screen
printf()
How I/O Works
User types
scanf() reads
Stored in variable
printf() displays
The stdio.h Header
All I/O functions require the <stdio.h> header (Standard Input/Output). This must be included at the top of your program.
#include <stdio.h>
// Now you can use: printf, scanf, getchar, putchar, fgets, puts...
Common I/O Functions
| Function | Purpose | Type |
|---|---|---|
| printf() | Print formatted output to screen | Output |
| scanf() | Read formatted input from keyboard | Input |
| puts() | Print string with automatic newline | Output |
| fgets() | Read full line (with spaces) safely | Input |
| getchar() | Read single character | Input |
| putchar() | Print single character | Output |
02The printf() Function (Output)
printf() is used to print formatted output to the screen. It's one of the most commonly used functions in C.
1.Printing Text (String)
#include <stdio.h>int main() { printf("Hello, World!"); return 0;}The text inside " " is called a string.
2.Printing a Variable
#include <stdio.h>int main() { int age = 25; printf("%d", age); return 0;}%d is a format specifier — a placeholder that gets replaced by the value.
3.Printing Text with Variables
#include <stdio.h>int main() { int age = 25; printf("I am %d years old", age); return 0;}4.Printing Multiple Variables
#include <stdio.h>int main() { int age = 25; float height = 5.9; printf("Age: %d, Height: %.1f", age, height); return 0;}5.Using Newline (\n)
#include <stdio.h>int main() { printf("Line 1\n"); printf("Line 2\n"); printf("Line 3"); return 0;}Line 1
Line 2
Line 3
\n is an escape sequence that moves to a new line.
Complete Example - All Data Types
#include <stdio.h>int main() { int age = 25; float price = 19.99; char grade = 'A'; char name[] = "John"; printf("Name: %s\n", name); // String printf("Age: %d\n", age); // Integer printf("Price: %.2f\n", price); // Float (2 decimals) printf("Grade: %c\n", grade); // Character return 0;}Name: John
Age: 25
Price: 19.99
Grade: A
03Format Specifiers
What are Format Specifiers?
Format specifiers are placeholders that tell printf/scanf what type of data to expect and how to format it.
// The % symbol starts a format specifier
printf("I am %d years old", 25);
// Output: I am 25 years old
How It Works
"Age: %d"
Format String
25
Value
Age: 25
Output
The %d placeholder gets replaced by the value 25
| Specifier | Data Type | Example | Output |
|---|---|---|---|
| %d or %i | int (signed) | printf("%d", 42) | 42 |
| %u | unsigned int | printf("%u", 42) | 42 |
| %ld | long int | printf("%ld", 123456789L) | 123456789 |
| %lld | long long int | printf("%lld", 9999999999LL) | 9999999999 |
| %f | float / double | printf("%f", 3.14) | 3.140000 |
| %.2f | float (2 decimals) | printf("%.2f", 3.14159) | 3.14 |
| %e | Scientific notation | printf("%e", 12345.67) | 1.234567e+04 |
| %c | char | printf("%c", 'A') | A |
| %s | string (char array) | printf("%s", "Hello") | Hello |
| %x / %X | Hexadecimal | printf("%x", 255) | ff |
| %o | Octal | printf("%o", 8) | 10 |
| %p | Pointer address | printf("%p", &x) | 0x7fff... |
| %% | Literal % | printf("100%%") | 100% |
Width and Precision Modifiers
Anatomy of a Format Specifier
1#include <stdio.h>23int main() {4 printf("[%d]\n", 42); // Normal: [42]5 printf("[%5d]\n", 42); // Width 5: [ 42]6 printf("[%05d]\n", 42); // Zero-pad: [00042]7 printf("[%-5d]\n", 42); // Left-align: [42 ]8 9 printf("[%.2f]\n", 3.14159); // 2 decimals: [3.14]10 printf("[%8.2f]\n", 3.14); // Width 8: [ 3.14]11 return 0;12}[42]
[ 42]
[00042]
[3.14]
[ 3.14]
A Escape Sequences
Escape sequences are special characters that start with a backslash \. They represent characters that can't be typed directly.
| Escape | Meaning | Example |
|---|---|---|
| \n | New line | printf("Line1\nLine2") |
| \t | Tab (horizontal) | printf("Col1\tCol2") |
| \\ | Backslash | printf("C:\\path") |
| \" | Double quote | printf("Say \"Hi\"") |
| \' | Single quote | char c = '\'' |
| \0 | Null character | String terminator |
Example: Using Escape Sequences
#include <stdio.h>int main() { printf("Name\tAge\tCity\n"); printf("John\t25\tNYC\n"); printf("She said \"Hello\"\n"); printf("Path: C:\\Users\\John\n"); return 0;}Name Age City
John 25 NYC
She said "Hello"
Path: C:\Users\John
04printf Variants
| Function | Description | Use Case |
|---|---|---|
| printf() | Print to stdout (screen) | Normal console output |
| fprintf() | Print to file stream | Write to files, stderr |
| sprintf() | Print to string buffer | Format string in memory |
| snprintf() | Print to string (size limited) | Safe string formatting |
1#include <stdio.h>23int main() {4 char buf[50];5 6 printf("Hello!\n"); // To screen7 fprintf(stderr, "Error!\n"); // To stderr8 sprintf(buf, "Age: %d", 25); // To string9 printf("Buffer: %s\n", buf);10 11 return 0;12}Hello!
Error!
Buffer: Age: 25
Always Use snprintf!
sprintf() can cause buffer overflow! Always prefer snprintf() which limits the output to your buffer size.
05The scanf() Function (Input)
scanf() is used to read user input from the keyboard. It takes the format string and the addresses of variables where input will be stored.
Syntax
Don't forget the & before the variable!
1.Reading an Integer
#include <stdio.h>int main() { int age; printf("Enter your age: "); scanf("%d", &age); printf("You are %d years old\n", age); return 0;}Enter your age: 25 ← (user types)
You are 25 years old
%d reads an integer. &age gives the memory address of age.
2.Reading a Float/Double
#include <stdio.h>int main() { float price; printf("Enter price: "); scanf("%f", &price); printf("Price is $%.2f\n", price); return 0;}Enter price: 19.99
Price is $19.99
3.Reading a Character
#include <stdio.h>int main() { char grade; printf("Enter your grade: "); scanf(" %c", &grade); // Note: space before %c printf("Your grade is: %c\n", grade); return 0;}Enter your grade: A
Your grade is: A
The space before %c skips any leftover whitespace/newlines.
4.Reading a String (Single Word)
#include <stdio.h>int main() { char name[50]; printf("Enter your name: "); scanf("%s", name); // No & for arrays! printf("Hello, %s!\n", name); return 0;}Enter your name: John
Hello, John!
%s stops at the first space! "John Doe" becomes just "John". Use fgets() for full lines.
5.Reading Multiple Values
#include <stdio.h>int main() { char name[20]; int age; float height; printf("Enter name, age, height: "); scanf("%s %d %f", name, &age, &height); printf("Name: %s\n", name); printf("Age: %d\n", age); printf("Height: %.1f\n", height); return 0;}Enter name, age, height: John 25 5.9
Name: John
Age: 25
Height: 5.9
Why is & Required?
scanf() needs to store the value into your variable. To do this, it needs the memory address of the variable (where it lives in memory). The & operator gives that address.
Common scanf Mistakes
- • Forgot &:
scanf("%d", num)→ Crash! Use&num - • %s stops at space: "John Doe" reads only "John"
- • No & for arrays:
scanf("%s", name)is correct (name is already an address)
06scanf Variants
| Function | Description | Use Case |
|---|---|---|
| scanf() | Read from stdin (keyboard) | Normal user input |
| fscanf() | Read from file stream | Parse file data |
| sscanf() | Read from string | Parse string data |
1#include <stdio.h>23int main() {4 char str[] = "Bob 25";5 char name[20];6 int age;7 8 // sscanf - parse from string9 sscanf(str, "%s %d", name, &age);10 printf("Name: %s, Age: %d\n", name, age);11 12 return 0;13}Name: Bob, Age: 25
07Reading Strings with Spaces (fgets)
Remember that scanf("%s") stops at the first space. To read a full line including spaces, use fgets().
Problem with scanf for Strings
#include <stdio.h>int main() { char name[50]; printf("Enter full name: "); scanf("%s", name); // Problem: stops at space! printf("Name: %s\n", name); return 0;}Enter full name: John Doe
Name: John
"Doe" is lost!
✓Solution: Use fgets()
#include <stdio.h>int main() { char name[50]; printf("Enter full name: "); fgets(name, sizeof(name), stdin); // Reads full line! printf("Hello, %s", name); return 0;}Enter full name: John Doe
Hello, John Doe
fgets(buffer, size, stdin): reads up to size-1 characters safely.
Simple String Output (puts/fputs)
For simple string output, you can use puts() or fputs():
puts() - Print String with Newline
#include <stdio.h>int main() { puts("Hello, World!"); // Adds \n automatically puts("This is line 2"); return 0;}Hello, World!
This is line 2
fputs() - Print to Any Stream
#include <stdio.h>int main() { fputs("Hello!", stdout); // No automatic newline fputs(" World!\n", stdout); return 0;}Hello! World!
fputs() can also write to files (not just stdout).
A Single Character I/O
getchar() - Read Character
char ch = getchar();printf("You typed: %c", ch);Input: A
You typed: A
putchar() - Print Character
putchar('H');putchar('i');putchar('!');Hi!
When to Use What?
- • printf() - formatted output with variables
- • puts() - simple string with automatic newline
- • scanf() - single word or formatted input
- • fgets() - full line with spaces
08main() with Command-Line Arguments
What are Command-Line Arguments?
Command-line arguments let you pass data to your program when you run it:
./program arg1 arg2 arg3
main() Signatures
Without arguments:
int main(void)
int main()
With arguments:
int main(int argc, char *argv[])
int main(int argc, char **argv)
| Parameter | Name | Description |
|---|---|---|
| argc | Argument Count | Number of arguments (including program name) |
| argv | Argument Vector | Array of strings (the actual arguments) |
| argv[0] | Program Name | Always the name of the program |
| argv[1..n] | User Arguments | Arguments passed by the user |
1#include <stdio.h>23int main(int argc, char *argv[]) {4 printf("Arguments: %d\n", argc);5 6 for (int i = 0; i < argc; i++) {7 printf("argv[%d] = %s\n", i, argv[i]);8 }9 10 if (argc >= 2) {11 printf("Hello, %s!\n", argv[1]);12 }13 return 0;14}Arguments: 2
argv[0] = ./program
argv[1] = Bob
Hello, Bob!
String to Number Conversion
| Function | Converts To | Example |
|---|---|---|
| atoi() | int | atoi("42") → 42 |
| atof() | double | atof("3.14") → 3.14 |
1#include <stdio.h>2#include <stdlib.h>34int main(int argc, char *argv[]) {5 if (argc >= 2) {6 int num = atoi(argv[1]); // String to int7 printf("Number: %d\n", num);8 }9 return 0;10}Number: 42
!Code Pitfalls: Common Mistakes & What to Watch For
These are the most common mistakes that trip up beginners. Study them carefully to avoid hours of debugging!
Forgetting & in scanf
scanf("%d", num); // Wrong!
scanf("%d", &num); // Correct!
Wrong format specifier
printf("%d", 3.14); // float with %d!
printf("%f", 3.14); // Correct!
Buffer overflow with %s
char s[10];
scanf("%s", s); // Dangerous!
char s[10];
scanf("%9s", s); // Safe!
Newline issue with %c
scanf("%c", &ch); // Reads leftover \\n
scanf(" %c", &ch); // Space skips whitespace
Not checking return value
if (scanf("%d", &num) != 1) {
printf("Invalid input!\\n");
}
Watch Out When Copying Code!
Why beginners get I/O Wrong!
Input/Output in C has many subtle pitfalls that Code often mishandles because they require understanding buffer behavior and edge cases:
1. Missing the & in scanf
Copied code often generates scanf("%d", num) instead ofscanf("%d", &num). This compiles but crashes or produces garbage because scanf needs the address to store input.
2. Buffer Overflow with gets()
Copied code might still use the deprecated gets() function, which has no length limit and is a massive security hole. Always usefgets(str, size, stdin) instead.
3. Ignoring the Newline Problem
When you scanf("%d", &num) thenscanf("%c", &ch), the second reads the leftover newline! Code rarely adds the space fix: scanf(" %c", &ch).
Test Strategy: Always test copied I/O code with: (1) empty input, (2) input with spaces, (3) very long input, (4) mixed number/character input.
11Frequently Asked Questions
Q:Why do I need & with scanf but not with printf?
A: printf justreads the value to display it — it only needs the value itself.scanf needs to write into the variable, so it needs the memory address where the variable lives. That's what & gives: the address. Exception: arrays (strings) are already addresses, soscanf("%s", str) doesn't need &.
Q:Why does scanf skip my second input when reading characters?
A: After you type a number and press Enter, the newline character (\n) stays in the input buffer. Whenscanf("%c", ...) runs, it reads that leftover newline instead of waiting for new input. Fix: Add a space before %c:scanf(" %c", &ch) — the space tells scanf to skip any whitespace first.
Q:What's the difference between scanf and fgets for strings?
A: scanf("%s", str) stops at the first whitespace — so "Hello World" only reads "Hello".fgets(str, size, stdin) reads the entire line including spaces. Also, fgets has a size limit preventing buffer overflow, making it safer. Use fgets for any user input that might contain spaces (names, sentences, etc.).
Q:What does %d vs %i mean? Are they the same?
A: In printf, %d and %i are identical. In scanf, they differ:%d reads decimal numbers only, while%i auto-detects the base (0x for hex, 0 for octal, else decimal). For beginners, just use %d — it's simpler and safer.
Q:How do I print a percentage sign % in printf?
A: Use double percent:printf("50%%") prints "50%". Since % signals a format specifier, you need %% to print a literal percent sign. Similarly, use \\ for backslash, \" for quote, and \n for newline.
Q:Why does printf show wrong values for my float?
A: Common causes: (1) Using %d instead of %f — %d expects an int, not a float. (2) Using%f for a double in scanf — use %lf for double in scanf (though %f works in printf because floats are promoted to double). Always match the format specifier to the data type!
Q:How do I limit how many decimal places printf shows?
A: Use precision:printf("%.2f", 3.14159) prints "3.14" (2 decimal places). You can also set total width: printf("%8.2f", value) right-aligns in 8 characters with 2 decimals. Use %-8.2f for left-align.
12Summary
Key Takeaways
- •printf("text"): Print text to screen
- •printf("%d", var): Print variable using format specifier
- •scanf("%d", &var): Read input into variable (don't forget &!)
- •Format specifiers: %d (int), %f (float), %c (char), %s (string)
- •Escape sequences: \n (newline), \t (tab), \\ (backslash)
- •fgets(): Read full line with spaces (safer than scanf for strings)
- •puts(): Print string with automatic newline
- •argc/argv: Access command-line arguments in main()
Quick Reference
Output Functions
printf("Hello %s", name);
puts("Simple line");
putchar('A');
Input Functions
scanf("%d", &num);
fgets(str, 50, stdin);
ch = getchar();
Test Your Knowledge
Related Tutorials
Escape Characters in C
Master escape sequences like \n (newline), \t (tab), \\ (backslash), and \" (quotes). Essential for formatting output and handling special characters.
Data Types & Variables
Learn to store different kinds of data: numbers (int), decimals (float), and characters (char). Understand how much memory each type uses.
Keywords in C
Learn all 32 reserved words in C that have special meaning. These words are reserved by C and cannot be used as variable names.
Have Feedback?
Found something missing or have ideas to improve this tutorial? Let us know on GitHub!