Docs
README
C++ Input and Output
Table of Contents
- •Introduction to I/O Streams
- •The iostream Library
- •Standard Output with cout
- •Standard Input with cin
- •Output Formatting
- •Input Handling and Validation
- •String Input with getline
- •Error Streams
- •Buffer Management
- •Best Practices
Introduction to I/O Streams
C++ uses a stream-based model for input and output. Think of streams as channels through which data flows:
┌─────────────┐ ┌───────────────┐ ┌─────────────┐
│ Keyboard │────▶│ Input Stream │────▶│ Program │
└─────────────┘ │ (cin) │ └─────────────┘
└───────────────┘
┌─────────────┐ ┌───────────────┐ ┌─────────────┐
│ Program │────▶│ Output Stream │────▶│ Screen │
└─────────────┘ │ (cout) │ └─────────────┘
└───────────────┘
Stream Concept
A stream is:
- •An abstraction representing a device where characters are read or written
- •A sequence of bytes flowing from source to destination
- •Buffered for efficiency (data collected before transfer)
Key Benefits
- •Uniform interface: Same syntax for console, files, strings
- •Type safety: Compiler checks types automatically
- •Extensibility: Can add custom types to stream system
The iostream Library
Including iostream
#include <iostream> // Required for I/O operations
using namespace std; // Optional: allows cout instead of std::cout
Standard Stream Objects
| Object | Type | Purpose |
|---|---|---|
cin | istream | Standard input (keyboard) |
cout | ostream | Standard output (screen) |
cerr | ostream | Standard error (unbuffered) |
clog | ostream | Standard log (buffered error) |
Stream Operators
| Operator | Name | Usage |
|---|---|---|
<< | Insertion | Send data TO stream (output) |
>> | Extraction | Get data FROM stream (input) |
cout << "Hello"; // Insert "Hello" into output stream
cin >> variable; // Extract value from input stream
Standard Output with cout
Basic Output
#include <iostream>
using namespace std;
int main() {
// Simple text output
cout << "Hello, World!";
// Output with newline
cout << "First line" << endl;
cout << "Second line\n";
return 0;
}
Chaining Output
The << operator returns the stream, allowing chaining:
// All equivalent:
cout << "Name: " << "Alice" << ", Age: " << 25 << endl;
// Same as:
cout << "Name: ";
cout << "Alice";
cout << ", Age: ";
cout << 25;
cout << endl;
Output Different Types
int age = 25;
double price = 19.99;
char grade = 'A';
string name = "Bob";
bool active = true;
cout << "Age: " << age << endl; // Integer
cout << "Price: $" << price << endl; // Double
cout << "Grade: " << grade << endl; // Character
cout << "Name: " << name << endl; // String
cout << "Active: " << active << endl; // Boolean (prints 1 or 0)
endl vs \n
| Method | Description | When to Use |
|---|---|---|
endl | Newline + flush buffer | Interactive output, before input |
\n | Just newline | Performance-critical, bulk output |
// endl flushes the buffer (ensures immediate display)
cout << "Enter name: " << flush; // Just flush, no newline
cout << "Prompt: " << endl; // Newline and flush
// \n is faster for bulk operations
for (int i = 0; i < 1000; i++) {
cout << i << "\n"; // Faster than endl
}
Standard Input with cin
Basic Input
#include <iostream>
using namespace std;
int main() {
int age;
cout << "Enter your age: ";
cin >> age;
cout << "You are " << age << " years old." << endl;
return 0;
}
Input Multiple Values
int a, b, c;
// Input on separate lines
cout << "Enter three numbers:\n";
cin >> a;
cin >> b;
cin >> c;
// Or chain them (can be space or newline separated)
cout << "Enter three numbers: ";
cin >> a >> b >> c;
Input Different Types
int age;
double salary;
char initial;
string firstName; // Note: reads only until whitespace
cout << "Enter age: ";
cin >> age;
cout << "Enter salary: ";
cin >> salary;
cout << "Enter initial: ";
cin >> initial;
cout << "Enter first name: ";
cin >> firstName; // "John Smith" would only read "John"
How cin Works
Input buffer: "42 3.14 A\n"
▲
cin >> intVar; // Reads 42, stops at space
▲
Input buffer: " 3.14 A\n"
▲
cin >> doubleVar; // Skips whitespace, reads 3.14
▲
Input buffer: " A\n"
▲
cin >> charVar; // Skips whitespace, reads 'A'
▲
Key Points:
- •
>>skips leading whitespace - •Stops reading at whitespace (for strings) or invalid character
- •Leaves newline and remaining characters in buffer
Output Formatting
The iomanip Library
#include <iostream>
#include <iomanip> // For setw, setprecision, etc.
using namespace std;
Field Width: setw
cout << setw(10) << 42 << endl; // " 42"
cout << setw(10) << "Hello" << endl; // " Hello"
// setw only affects NEXT output
cout << setw(5) << 1 << setw(5) << 2 << setw(5) << 3 << endl;
// " 1 2 3"
Fill Character: setfill
cout << setfill('*') << setw(10) << 42 << endl; // "********42"
cout << setfill('0') << setw(5) << 7 << endl; // "00007"
cout << setfill('-') << setw(20) << "" << endl; // "--------------------"
Alignment
cout << left << setw(10) << "Left" << "|" << endl; // "Left |"
cout << right << setw(10) << "Right" << "|" << endl; // " Right|"
cout << internal << setw(10) << -42 << endl; // "- 42"
Floating-Point Precision
double pi = 3.14159265358979;
// Default precision (6 significant digits)
cout << pi << endl; // 3.14159
// Set precision
cout << setprecision(3) << pi << endl; // 3.14
cout << setprecision(10) << pi << endl; // 3.141592654
// Fixed notation (digits after decimal)
cout << fixed << setprecision(2) << pi << endl; // 3.14
// Scientific notation
cout << scientific << setprecision(2) << pi << endl; // 3.14e+00
Number Bases
int num = 255;
cout << "Decimal: " << dec << num << endl; // 255
cout << "Hex: " << hex << num << endl; // ff
cout << "Octal: " << oct << num << endl; // 377
// Show base prefix
cout << showbase;
cout << "Hex: " << hex << num << endl; // 0xff
cout << "Octal: " << oct << num << endl; // 0377
// Uppercase hex
cout << uppercase << hex << num << endl; // 0XFF
Boolean Output
bool flag = true;
cout << flag << endl; // 1
cout << boolalpha << flag << endl; // true
cout << noboolalpha << flag << endl; // 1
Formatting Table
| Manipulator | Effect | Sticky? |
|---|---|---|
setw(n) | Field width | No (one-time) |
setfill(c) | Fill character | Yes |
setprecision(n) | Decimal precision | Yes |
fixed | Fixed-point notation | Yes |
scientific | Scientific notation | Yes |
left | Left align | Yes |
right | Right align | Yes |
hex/dec/oct | Number base | Yes |
boolalpha | true/false for bools | Yes |
showbase | Show 0x, 0 prefix | Yes |
showpoint | Always show decimal | Yes |
Input Handling and Validation
Check Input Success
int num;
cout << "Enter a number: ";
if (cin >> num) {
cout << "You entered: " << num << endl;
} else {
cout << "Invalid input!" << endl;
}
Input State Flags
cin.good() // No errors
cin.eof() // End of file reached
cin.fail() // Logical error (wrong type)
cin.bad() // Read/write error
Clearing Errors
int num;
cout << "Enter a number: ";
cin >> num;
if (cin.fail()) {
cout << "Invalid input! Try again." << endl;
cin.clear(); // Clear error flags
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Clear buffer
cout << "Enter a number: ";
cin >> num;
}
Input Validation Loop
#include <limits> // For numeric_limits
int getValidInteger() {
int num;
while (true) {
cout << "Enter an integer: ";
if (cin >> num) {
// Clear any remaining input
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return num;
}
cout << "Invalid input! Please enter an integer." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
Range Validation
int getNumberInRange(int min, int max) {
int num;
while (true) {
cout << "Enter a number (" << min << "-" << max << "): ";
if (cin >> num && num >= min && num <= max) {
return num;
}
cout << "Invalid! Must be between " << min << " and " << max << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
String Input with getline
The Problem with cin >> string
string fullName;
cout << "Enter your full name: ";
cin >> fullName; // Only reads first word!
// Input: "John Smith"
// fullName = "John" (Smith left in buffer)
Solution: getline()
string fullName;
cout << "Enter your full name: ";
getline(cin, fullName); // Reads entire line
// Input: "John Smith"
// fullName = "John Smith"
Mixing cin >> and getline()
int age;
string name;
cout << "Enter age: ";
cin >> age;
cout << "Enter name: ";
getline(cin, name); // PROBLEM: reads empty line!
The Issue:
Buffer after "cin >> age": "\n" (newline still there)
getline reads the newline immediately, gets empty string
Solution: Clear the newline first
int age;
string name;
cout << "Enter age: ";
cin >> age;
cin.ignore(); // Ignore the newline
cout << "Enter name: ";
getline(cin, name); // Now works correctly
getline with Delimiter
string data;
// Read until newline (default)
getline(cin, data);
// Read until comma
getline(cin, data, ',');
// Read until specific character
getline(cin, data, '#');
Error Streams
cerr - Unbuffered Error Output
cerr << "Error: File not found!" << endl;
- •Unbuffered: Output appears immediately
- •Use for: Error messages, crash diagnostics
- •Separate from cout (can redirect separately)
clog - Buffered Log Output
clog << "Debug: Processing started" << endl;
- •Buffered: More efficient for multiple messages
- •Use for: Logging, debug messages
Redirecting Streams
# In terminal:
./program > output.txt # Redirect cout to file
./program 2> errors.txt # Redirect cerr to file
./program > out.txt 2>&1 # Both to same file
./program 2>/dev/null # Discard errors
Practical Usage
void processFile(const string& filename) {
// Normal output to cout
cout << "Processing: " << filename << endl;
// Errors to cerr
if (!fileExists(filename)) {
cerr << "Error: Cannot find " << filename << endl;
return;
}
// Debug info to clog
clog << "Debug: File size = " << getFileSize(filename) << endl;
}
Buffer Management
What is Buffering?
Program Output: "H" "e" "l" "l" "o"
↓ ↓ ↓ ↓ ↓
┌─────────────────────┐
│ Output Buffer │ Buffer collects data
│ [H][e][l][l][o] │
└─────────────────────┘
│
│ Flush (when full, endl, or explicit)
▼
┌─────────────────────┐
│ Screen │ "Hello" appears
└─────────────────────┘
When Buffer Flushes
- •Buffer becomes full
- •
endlis used - •
flushis called - •Program ends normally
- •Input is requested (cin)
Explicit Flushing
cout << "Processing..." << flush; // Flush without newline
doLongOperation();
cout << "Done!" << endl;
// Or use manipulator
cout << "Data" << flush;
Buffer States
// Tie cin to cout (default)
// Ensures cout is flushed before cin reads
cin.tie(&cout); // Default behavior
// Untie for performance (be careful!)
cin.tie(nullptr);
// Sync with C stdio (default: synced)
ios_base::sync_with_stdio(true); // Default
// Disable sync for performance
ios_base::sync_with_stdio(false);
Best Practices
1. Always Prompt Before Input
// Good
cout << "Enter your age: ";
cin >> age;
// Bad (user doesn't know what to enter)
cin >> age;
2. Validate All User Input
int age;
while (!(cin >> age) || age < 0 || age > 150) {
cout << "Please enter a valid age (0-150): ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
3. Use getline for Strings with Spaces
string address;
cout << "Enter address: ";
getline(cin, address); // Not: cin >> address
4. Clear Buffer When Mixing cin >> and getline
int num;
string line;
cin >> num;
cin.ignore(); // Clear the newline!
getline(cin, line);
5. Use Appropriate Precision for Money
double price = 19.99;
cout << fixed << setprecision(2) << "$" << price << endl;
6. Format Tables Consistently
cout << left;
cout << setw(20) << "Name" << setw(10) << "Age" << setw(15) << "City" << endl;
cout << setfill('-') << setw(45) << "" << setfill(' ') << endl;
cout << setw(20) << "Alice" << setw(10) << 25 << setw(15) << "New York" << endl;
cout << setw(20) << "Bob" << setw(10) << 30 << setw(15) << "Boston" << endl;
7. Use cerr for Errors
if (error_condition) {
cerr << "Error: " << error_message << endl;
return 1;
}
8. Consider Performance
// For competitive programming or bulk output:
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
// Use '\n' instead of endl
cout << value << '\n';
Summary
| Task | Method |
|---|---|
| Output text | cout << "text" |
| Output variable | cout << variable |
| Newline | endl or "\n" |
| Input value | cin >> variable |
| Input line | getline(cin, string) |
| Format width | setw(n) |
| Format precision | setprecision(n) |
| Format fixed | fixed |
| Validate input | if (cin >> var) |
| Clear error | cin.clear() |
| Clear buffer | cin.ignore(...) |
| Error output | cerr << "error" |
Previous: Syntax and Structure | Next: Variables and Data Types