Input and Output
C++ provides two I/O systems: the classic C-style printf/scanf and the modern C++ stream library (iostream). Streams are type-safe and extensible — you can overload << and >> for your own types. This topic covers everything you need to read input and format output professionally.
The Standard Streams
#include <iostream>
using namespace std;
int main() {
// cout — standard output (screen)
cout << "Hello, World!\n";
// cerr — standard error (unbuffered, always visible even with redirected output)
cerr << "Error: something went wrong\n";
// clog — standard log (buffered standard error)
clog << "Info: program started\n";
// endl vs "\n"
cout << "With endl" << endl; // flushes buffer (slower)
cout << "With newline\n"; // just a newline (faster)
return 0;
}Note: Prefer "\n" over endl in performance-sensitive code. endl flushes the output buffer every time it is called, which is significantly slower when printing many lines.
Basic Output with cout
#include <iostream>
using namespace std;
int main() {
int age = 25;
double salary = 75000.50;
char grade = 'A';
bool active = true;
// Chain multiple values with <<
cout << "Age: " << age << "\n";
cout << "Salary: " << salary << "\n";
cout << "Grade: " << grade << "\n";
cout << boolalpha << "Active: " << active << "\n";
// Output:
// Age: 25
// Salary: 75000.5
// Grade: A
// Active: true
// Concatenation-style output
cout << "Name: " << "Alice" << ", Age: " << age << ", Grade: " << grade << "\n";
// Name: Alice, Age: 25, Grade: A
return 0;
}Formatted Output with iomanip
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double pi = 3.14159265358979;
// Precision
cout << pi << "\n"; // 3.14159 (default 6 significant digits)
cout << fixed << setprecision(2) << pi << "\n"; // 3.14
cout << fixed << setprecision(8) << pi << "\n"; // 3.14159265
cout << scientific << pi << "\n"; // 3.141593e+00
// Width and alignment
cout << setw(10) << "Name" << setw(8) << "Score" << "\n";
cout << setw(10) << "Alice" << setw(8) << 95 << "\n";
cout << setw(10) << "Bob" << setw(8) << 87 << "\n";
// Output:
// Name Score
// Alice 95
// Bob 87
// Left-align with setfill
cout << left << setfill('-') << setw(20) << "Hello" << "\n";
// Hello---------------
// Right-align (default)
cout << right << setfill('0') << setw(8) << 42 << "\n";
// 00000042
// Hexadecimal, octal, decimal
int n = 255;
cout << dec << n << "\n"; // 255
cout << hex << n << "\n"; // ff
cout << oct << n << "\n"; // 377
cout << hex << uppercase << n << "\n"; // FF
return 0;
}Basic Input with cin
#include <iostream>
#include <string>
using namespace std;
int main() {
// Read a single integer
int age;
cout << "Enter your age: ";
cin >> age;
cout << "Age: " << age << "\n";
// Read a double
double weight;
cout << "Enter weight (kg): ";
cin >> weight;
// Read a single word (stops at whitespace)
string firstName;
cout << "Enter first name: ";
cin >> firstName;
cout << "Hello, " << firstName << "!\n";
// Read multiple values at once
int x, y;
cout << "Enter two numbers: ";
cin >> x >> y;
cout << "Sum: " << x + y << "\n";
return 0;
}Reading Full Lines with getline
#include <iostream>
#include <string>
using namespace std;
int main() {
string fullName;
int age;
cout << "Enter age: ";
cin >> age;
// IMPORTANT: cin >> leaves '\n' in the buffer
// getline after cin >> will read empty line without this fix
cin.ignore(); // Discard the leftover newline
cout << "Enter full name: ";
getline(cin, fullName); // Reads the entire line including spaces
cout << "Name: " << fullName << ", Age: " << age << "\n";
// Reading multiple lines
string line;
cout << "Enter lines (type 'quit' to stop):\n";
while (getline(cin, line) && line != "quit") {
cout << "You said: " << line << "\n";
}
return 0;
}Input Validation
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int readPositiveInt(const string& prompt) {
int value;
while (true) {
cout << prompt;
if (cin >> value && value > 0) {
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return value;
}
// Input failed or value <= 0
cout << "Invalid input. Please enter a positive integer.\n";
cin.clear(); // Clear error flags
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Discard bad input
}
}
double readDouble(const string& prompt, double min, double max) {
double value;
while (true) {
cout << prompt;
if (cin >> value && value >= min && value <= max) {
return value;
}
cout << "Please enter a number between " << min << " and " << max << ".\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
int main() {
int count = readPositiveInt("How many items? ");
double price = readDouble("Price (0–1000): ", 0.0, 1000.0);
cout << "Total: " << count * price << "\n";
return 0;
}printf and scanf (C-Style)
Although cout/cin are preferred in C++, the C-style functions work in C++ and are sometimes used in competitive programming or performance-critical code:
#include <cstdio>
int main() {
// printf — formatted output
int age = 25;
double pi = 3.14159;
printf("Age: %d\n", age); // Age: 25
printf("Pi: %.4f\n", pi); // Pi: 3.1416
printf("Hex: %X\n", 255); // Hex: FF
printf("Sci: %e\n", pi); // Sci: 3.141590e+00
printf("%-10s|%5d\n", "Alice", 95);// Alice | 95
// scanf — formatted input (no type safety!)
int n;
scanf("%d", &n); // Note: & required for address
return 0;
}| Feature | cout / cin | printf / scanf |
|---|---|---|
| Type safety | Yes — compiler checks | No — format string mismatch = UB |
| Extensible | Yes — overload <</>> | No |
| Speed | Slightly slower (can be made fast) | Fast |
| Syntax | Intuitive | Compact but error-prone |
| Recommended for | Modern C++ | Performance-critical, competitive |
Practical Example: Formatted Report
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
using namespace std;
struct Student {
string name;
int score;
double gpa;
};
void printReport(const vector<Student>& students) {
const int W_NAME = 15;
const int W_SCORE = 8;
const int W_GPA = 8;
const int W_GRADE = 8;
// Header
cout << string(W_NAME + W_SCORE + W_GPA + W_GRADE + 3, '-') << "\n";
cout << left << setw(W_NAME) << "Name"
<< right << setw(W_SCORE) << "Score"
<< setw(W_GPA) << "GPA"
<< setw(W_GRADE) << "Grade" << "\n";
cout << string(W_NAME + W_SCORE + W_GPA + W_GRADE + 3, '-') << "\n";
// Rows
for (const auto& s : students) {
string grade = (s.score >= 90) ? "A" :
(s.score >= 80) ? "B" :
(s.score >= 70) ? "C" : "F";
cout << fixed << setprecision(2);
cout << left << setw(W_NAME) << s.name
<< right << setw(W_SCORE) << s.score
<< setw(W_GPA) << s.gpa
<< setw(W_GRADE) << grade << "\n";
}
cout << string(W_NAME + W_SCORE + W_GPA + W_GRADE + 3, '-') << "\n";
}
int main() {
vector<Student> students = {
{"Alice", 92, 3.9},
{"Bob", 78, 3.2},
{"Charlie", 85, 3.5},
{"Diana", 60, 2.1},
};
cout << "\n === Student Report ===\n\n";
printReport(students);
return 0;
}
// Output:
// === Student Report ===
//
// -------------------------------------------
// Name Score GPA Grade
// -------------------------------------------
// Alice 92 3.90 A
// Bob 78 3.20 B
// Charlie 85 3.50 B
// Diana 60 2.10 F
// -------------------------------------------Summary
cout,cin,cerr,clogare the four standard streams — usecerrfor errors- Chain values with
<<for output and>>for input cin >> strreads one word;getline(cin, str)reads the entire line- Always call
cin.ignore()aftercin >>beforegetlineto discard the leftover newline - Use
<iomanip>:setw(),setprecision(),fixed,left,right,setfill()for professional formatting - Validate user input with
cin.clear()andcin.ignore()to recover from bad input printf/scanfare faster but not type-safe — prefercout/cinin modern C++
Next, we'll dive into strings — std::string methods, manipulation, string_view, and the differences between C strings and C++ strings.