Docs
README
Input/Output in C (scanf, printf)
š Introduction
Input/Output (I/O) operations allow C programs to interact with users and external devices. The most common I/O functions are printf() for output and scanf() for input, both declared in <stdio.h>.
šÆ Standard I/O Streams
C provides three standard streams that are automatically opened when a program starts:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Standard Streams ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Keyboard āāāŗ stdin āāā ā
ā ā ā
ā ā¼ ā
ā āāāāāāāāāāāā ā
ā ā C Program ā ā
ā āāāāāāāāāāāā ā
ā ā ā ā
ā ā¼ ā¼ ā
ā stdout stderr ā
ā ā ā ā
ā ā¼ ā¼ ā
ā Screen Screen ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
| Stream | Type | Description | C Name |
|---|---|---|---|
| Standard Input | Input | Keyboard (by default) | stdin |
| Standard Output | Output | Screen (by default) | stdout |
| Standard Error | Output | Screen (for errors) | stderr |
š¤ Output with printf()
Basic Syntax:
int printf(const char *format, ...);
printf() returns the number of characters printed (negative on error).
Simple Output:
#include <stdio.h>
int main() {
printf("Hello, World!\n"); // Print string with newline
printf("Hello ");
printf("World\n"); // Continues on same line
return 0;
}
Format Specifiers:
int age = 25;
float price = 19.99;
char grade = 'A';
char name[] = "John";
printf("Age: %d\n", age); // Integer
printf("Price: %f\n", price); // Float
printf("Grade: %c\n", grade); // Character
printf("Name: %s\n", name); // String
Complete Format Specifier Table:
| Specifier | Type | Example | Output |
|---|---|---|---|
%d, %i | Signed integer | printf("%d", 42); | 42 |
%u | Unsigned integer | printf("%u", 42); | 42 |
%f | Float/double | printf("%f", 3.14); | 3.140000 |
%e, %E | Scientific notation | printf("%e", 1234.5); | 1.234500e+03 |
%g, %G | Shorter of %f or %e | printf("%g", 0.0001); | 0.0001 |
%c | Character | printf("%c", 'A'); | A |
%s | String | printf("%s", "Hi"); | Hi |
%p | Pointer address | printf("%p", &x); | 0x7ffd... |
%x, %X | Hexadecimal | printf("%x", 255); | ff |
%o | Octal | printf("%o", 64); | 100 |
%ld | Long int | printf("%ld", 100000L); | 100000 |
%lld | Long long int | printf("%lld", 10000000000LL); | 10000000000 |
%lf | Double (scanf only) | scanf("%lf", &d); | N/A |
%Lf | Long double | printf("%Lf", 3.14L); | 3.140000 |
%zu | size_t | printf("%zu", sizeof(int)); | 4 |
%% | Literal % | printf("%%"); | % |
Format Modifiers:
Format: %[flags][width][.precision][length]specifier
Width:
printf("[%10d]\n", 42); // [ 42] Right-aligned, width 10
printf("[%-10d]\n", 42); // [42 ] Left-aligned, width 10
printf("[%*d]\n", 10, 42); // [ 42] Width from variable
Precision:
printf("%.2f\n", 3.14159); // 3.14 (2 decimal places)
printf("%.5s\n", "Hello World"); // Hello (5 characters)
printf("%10.2f\n", 3.14159); // 3.14 (width 10, 2 decimals)
Flags:
| Flag | Meaning | Example | Output |
|---|---|---|---|
- | Left-align | %-10d, 42 | 42 |
+ | Show sign | %+d, 42 | +42 |
| Space for positive | % d, 42 | 42 |
0 | Zero-pad | %010d, 42 | 0000000042 |
# | Alternate form | %#x, 255 | 0xff |
Examples:
int num = 42;
float f = 3.14159;
// Width and alignment
printf("[%10d]\n", num); // [ 42]
printf("[%-10d]\n", num); // [42 ]
printf("[%010d]\n", num); // [0000000042]
// Precision
printf("[%.2f]\n", f); // [3.14]
printf("[%10.2f]\n", f); // [ 3.14]
printf("[%-10.2f]\n", f); // [3.14 ]
// Signs
printf("[%+d]\n", num); // [+42]
printf("[%+d]\n", -num); // [-42]
printf("[% d]\n", num); // [ 42]
// Alternate forms
printf("[%#x]\n", 255); // [0xff]
printf("[%#o]\n", 64); // [0100]
printf("[%#.0f]\n", 3.0); // [3.]
š„ Input with scanf()
Basic Syntax:
int scanf(const char *format, ...);
scanf() returns the number of successfully read items (0 or negative on failure).
ā ļø Important: Use Address-of Operator (&)
int age;
scanf("%d", &age); // CORRECT: Pass address
// scanf("%d", age); // WRONG: Undefined behavior!
Simple Input:
#include <stdio.h>
int main() {
int age;
float height;
char grade;
printf("Enter age: ");
scanf("%d", &age);
printf("Enter height: ");
scanf("%f", &height);
printf("Enter grade: ");
scanf(" %c", &grade); // Note: space before %c
printf("Age: %d, Height: %.2f, Grade: %c\n", age, height, grade);
return 0;
}
scanf Format Specifiers:
| Specifier | Reads | Example |
|---|---|---|
%d | Signed integer | scanf("%d", &num); |
%i | Integer (any base) | scanf("%i", &num); |
%u | Unsigned integer | scanf("%u", &num); |
%f | Float | scanf("%f", &f); |
%lf | Double | scanf("%lf", &d); |
%c | Single character | scanf("%c", &ch); |
%s | String (no spaces) | scanf("%s", str); |
%[...] | Scanset | scanf("%[^\n]", str); |
%n | Characters read so far | scanf("%d%n", &x, &n); |
Reading Multiple Values:
int a, b, c;
// Space-separated input
printf("Enter three integers: ");
scanf("%d %d %d", &a, &b, &c);
// Or any whitespace works
scanf("%d%d%d", &a, &b, &c); // Spaces optional in format
// Reading different types
int age;
float height;
char initial;
scanf("%d %f %c", &age, &height, &initial);
The Newline Problem:
int num;
char ch;
printf("Enter number: ");
scanf("%d", &num);
printf("Enter character: ");
scanf("%c", &ch); // PROBLEM: Reads leftover '\n'!
// Solutions:
// Solution 1: Add space before %c
scanf(" %c", &ch); // Space consumes whitespace
// Solution 2: Use getchar() to consume newline
scanf("%d", &num);
getchar(); // Consume '\n'
scanf("%c", &ch);
// Solution 3: Use %*c to skip the newline
scanf("%d%*c", &num); // %*c reads and discards a character
scanf("%c", &ch);
Reading Strings:
char name[50];
// Method 1: %s (stops at whitespace)
printf("Enter name: ");
scanf("%s", name); // Note: No & for arrays!
// Input: "John Doe" ā Only "John" is stored
// Method 2: %[^\n] (reads until newline)
scanf(" %[^\n]", name); // Reads whole line including spaces
// Input: "John Doe" ā "John Doe" is stored
// Method 3: Limit input length (SAFE)
scanf("%49s", name); // Max 49 chars + null terminator
scanf("%49[^\n]", name); // Max 49 chars with spaces
Return Value Checking:
int num;
printf("Enter a number: ");
if (scanf("%d", &num) != 1) {
printf("Invalid input!\n");
return 1;
}
printf("You entered: %d\n", num);
š” Character I/O: getchar() and putchar()
getchar() - Read Single Character:
#include <stdio.h>
int main() {
int ch; // Use int, not char (for EOF detection)
printf("Enter a character: ");
ch = getchar();
printf("You entered: ");
putchar(ch);
putchar('\n');
return 0;
}
putchar() - Write Single Character:
putchar('A'); // Print 'A'
putchar('\n'); // Print newline
putchar(65); // Print 'A' (ASCII value)
Reading a Line Character by Character:
int ch;
printf("Enter text (press Enter to stop): ");
while ((ch = getchar()) != '\n') {
putchar(ch);
}
putchar('\n');
š String I/O: gets() and puts()
ā ļø Warning: Never Use gets()
gets() is unsafe and removed from C11. It doesn't check buffer size:
// DANGEROUS - Never use!
char buffer[10];
gets(buffer); // Can overflow buffer!
Use fgets() Instead:
char buffer[100];
printf("Enter a line: ");
fgets(buffer, sizeof(buffer), stdin); // Safe!
// Note: fgets keeps the newline character
// Remove it if needed:
buffer[strcspn(buffer, "\n")] = '\0';
puts() - Print String with Newline:
puts("Hello, World!"); // Automatically adds newline
// Equivalent to: printf("Hello, World!\n");
š Buffer Flushing
fflush() - Flush Output Buffer:
printf("Loading");
for (int i = 0; i < 5; i++) {
printf(".");
fflush(stdout); // Force output immediately
sleep(1);
}
printf("\n");
Clearing Input Buffer:
// Method 1: Read and discard until newline
int c;
while ((c = getchar()) != '\n' && c != EOF);
// Method 2: Using scanf
scanf("%*[^\n]"); // Discard until newline
scanf("%*c"); // Discard newline itself
š Formatted I/O Examples
Creating Tables:
printf("%-10s %10s %10s\n", "Name", "Age", "Score");
printf("%-10s %10s %10s\n", "----", "---", "-----");
printf("%-10s %10d %10.2f\n", "Alice", 25, 95.50);
printf("%-10s %10d %10.2f\n", "Bob", 30, 88.75);
printf("%-10s %10d %10.2f\n", "Charlie", 22, 92.00);
Output:
Name Age Score
---- --- -----
Alice 25 95.50
Bob 30 88.75
Charlie 22 92.00
Progress Bar:
for (int i = 0; i <= 100; i += 10) {
printf("\r[%-20s] %3d%%", "####################" + (20 - i/5), i);
fflush(stdout);
usleep(100000); // Sleep 100ms
}
printf("\n");
Hexdump:
unsigned char data[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F};
for (int i = 0; i < sizeof(data); i++) {
printf("%02X ", data[i]);
}
printf("\n");
// Output: 48 65 6C 6C 6F
ā ļø Common Mistakes
1. Missing & in scanf:
int x;
scanf("%d", x); // WRONG: crashes or corrupts memory
scanf("%d", &x); // CORRECT
2. Wrong Format Specifier:
float f = 3.14;
scanf("%d", &f); // WRONG: expects int
scanf("%f", &f); // CORRECT
double d;
scanf("%f", &d); // WRONG for double
scanf("%lf", &d); // CORRECT for double
3. Buffer Overflow with %s:
char name[10];
scanf("%s", name); // DANGEROUS: could overflow
scanf("%9s", name); // SAFE: max 9 chars + null
4. Not Checking Return Value:
// Bad: No error checking
scanf("%d", &num);
// Good: Check for valid input
if (scanf("%d", &num) != 1) {
printf("Invalid input\n");
}
5. Mixing scanf and getchar:
scanf("%d", &num);
char ch = getchar(); // Gets '\n' from previous input!
// Fix:
scanf("%d", &num);
getchar(); // Consume the newline first
char ch = getchar(); // Now gets actual character
ā Best Practices
- ā¢Always check scanf() return value for input validation
- ā¢Use field width with %s to prevent buffer overflow:
%49s - ā¢Prefer fgets() over scanf() for strings - safer and more flexible
- ā¢Use appropriate format specifiers -
%lffor double in scanf - ā¢Add space before %c when following other inputs:
" %c" - ā¢Flush stdout when printing without newline and expecting input
- ā¢Initialize buffers before reading into them
- ā¢Handle EOF in character input loops
š Key Takeaways
- ā¢printf() displays formatted output; scanf() reads formatted input
- ā¢Format specifiers must match the variable type
- ā¢scanf requires address (using
&) except for arrays - ā¢Whitespace in scanf skips whitespace in input
- ā¢Check return values to handle input errors
- ā¢Buffer overflow is a major security concern - always limit input size
- ā¢The newline problem requires special handling with character input
āļø Next Topic
Continue to Operators to learn about arithmetic, relational, logical, and bitwise operators.