Input & Output
How C++ programs talk to the outside world through streams — reading with std::cin, writing with std::cout, and formatting output precisely with <iomanip>.
Input and output, commonly called I/O, allow a C++ program to communicate with the outside world. A program can: receive data from the user, display information on the screen, read characters or lines, write formatted output, and read and write files through streams. C++ provides its primary stream-based I/O facilities through the <iostream> header.
What Is Input and Output?
Input means data entering the program: User → Input → C++ Program.
The program waits for input and stores the value in age.
Output means data leaving the program: C++ Program → Output → Screen.
int age;
std::cin >> age;std::cout << age;C++ Stream Concept
C++ uses the concept of a stream for I/O. A stream can be thought of as a flow of data.
The same stream-based design is also used for file I/O and other I/O facilities.
Input stream: External source → std::cin → Program
Output stream: Program → std::cout → External destination<iostream>
The standard header for console input and output is:
It provides important stream objects such as std::cin, std::cout, std::cerr, and std::clog. Their basic purposes:
#include <iostream>Stream Purpose
------------ --------------------------
std::cin Standard input
std::cout Standard output
std::cerr Error output
std::clog Logging/diagnostic outputstd::cout
std::cout is used for standard output.
Output: Hello, World!
#include <iostream>
int main()
{
std::cout << "Hello, World!";
return 0;
}The Output Operator <<
The operator << is called the insertion operator when used with an output stream.
The value 100 is inserted into the output stream.
Output: Age: 25. Multiple values can be chained; this is called chained output.
std::cout << 100;std::cout << "Age: " << 25;Printing Different Data Types
C++ streams can output many built-in types directly.
By default, bool is normally displayed as 1 for true and 0 for false.
#include <iostream>
int main()
{
int age = 25;
double temperature = 36.5;
char grade = 'A';
bool active = true;
std::cout << age << '\n';
std::cout << temperature << '\n';
std::cout << grade << '\n';
std::cout << active << '\n';
return 0;
}Printing bool as true or false
C++ provides the boolalpha stream manipulator.
This returns output to numeric Boolean display.
#include <iostream>
int main()
{
bool isReady = true;
std::cout << std::boolalpha << isReady;
return 0;
}std::cout << std::noboolalpha;New Lines
There are several ways to move to a new line.
Both produce a newline. However, std::endl also flushes the output stream.
For ordinary output, std::cout << "Hello\n"; is often preferable. Use std::endl when you specifically need the flush behavior.
std::cout << "Hello\n";
std::cout << "Hello" << std::endl;Multiple Lines
You can chain multiple lines:
This style can keep related output readable.
std::cout << "Name: Rina\n"
<< "Age: 25\n"
<< "Status: Active\n";Name: Rina
Age: 25
Status: Activestd::cin
std::cin is the standard input stream.
If the user enters 25, the program stores 25 in age.
#include <iostream>
int main()
{
int age;
std::cin >> age;
std::cout << "Age: " << age << '\n';
return 0;
}The Input Operator >>
The operator >> is called the extraction operator when used with an input stream.
It extracts formatted input from std::cin and stores it in number.
int number;
std::cin >> number;Reading Multiple Values
Multiple values can be read using chained extraction:
If the user enters "25 172.5" then age = 25, height = 172.5. Whitespace such as spaces and newlines generally separates formatted input values.
int age;
double height;
std::cin >> age >> height;Reading Different Types
The stream extraction operation interprets the input according to the destination type.
#include <iostream>
int main()
{
int age;
double salary;
char grade;
std::cin >> age;
std::cin >> salary;
std::cin >> grade;
std::cout << age << '\n';
std::cout << salary << '\n';
std::cout << grade << '\n';
return 0;
}Reading Strings with std::cin
For a std::string:
If the user enters "Rina" the string becomes "Rina".
operator>> stops at whitespace. For "Rina Sahu" only "Rina" is extracted into name.
#include <iostream>
#include <string>
int main()
{
std::string name;
std::cin >> name;
std::cout << name;
return 0;
}std::getline
When an entire line is required, use std::getline().
Input: Rina Sahu. Output: Name: Rina Sahu. Unlike std::cin >> name, std::getline can read spaces within the line.
#include <iostream>
#include <string>
int main()
{
std::string name;
std::getline(std::cin, name);
std::cout << "Name: " << name << '\n';
return 0;
}std::cin >> vs std::getline
A quick comparison of the two approaches:
std::cin >> value std::getline
Reads formatted values Yes No, reads a line
Stops at whitespace Usually yes No
Reads spaces inside string No Yes
Common use Numbers/individual Full text lines
tokensstd::string name;
std::cin >> name; // input "Rina Sahu" -> name == "Rina"
std::getline(std::cin, name); // input "Rina Sahu" -> name == "Rina Sahu"The getline + cin >> Problem
A common issue occurs when formatted extraction is followed by std::getline.
Suppose the user enters "25" then "Rina Sahu" on the next line. After reading 25, the newline remains in the input stream. getline may immediately consume that remaining newline and produce an empty string.
A common solution is:
Required header: #include <limits>
int age;
std::string name;
std::cin >> age;
std::getline(std::cin, name);std::cin >> age;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, name);#include <iostream>
#include <string>
#include <limits>
int main()
{
int age;
std::string name;
std::cin >> age;
std::cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'\n'
);
std::getline(std::cin, name);
std::cout << "Age: " << age << '\n';
std::cout << "Name: " << name << '\n';
return 0;
}Whitespace Handling
Formatted extraction (std::cin >> value;) generally skips leading whitespace for most formatted input operations.
std::getline, however, reads characters up to the newline and therefore treats whitespace differently. Understanding this difference is important when mixing input methods.
int value;
std::cin >> value; // " 25" can still be read as 25Checking Input Success
Input operations can fail.
If the user enters "hello" the extraction cannot interpret it as an int. The stream enters a failure state.
You can check the result of the extraction directly, since a stream converts to a boolean success/failure indicator.
int age;
std::cin >> age;if (std::cin >> age)
{
std::cout << "Valid input\n";
}
else
{
std::cout << "Invalid input\n";
}Stream State
C++ streams maintain state information. Important states include good, fail, bad, and eof.
You can inspect them using std::cin.good(), std::cin.fail(), std::cin.bad(), and std::cin.eof().
if (std::cin.fail())
{
std::cout << "Input failed\n";
}Clearing an Input Error
After a formatted input failure, the stream may remain in a failed state. You can clear the state using std::cin.clear();
Clearing the state does not remove the invalid input from the input buffer. You may also need std::cin.ignore(...);
#include <iostream>
#include <limits>
int main()
{
int value;
std::cin >> value;
if (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'\n'
);
std::cout << "Invalid input\n";
}
return 0;
}Standard Error Output: std::cerr
std::cerr is commonly used for error and diagnostic messages.
std::cerr is an output stream distinct from std::cout.
std::cerr << "Error: Invalid input\n";if (value < 0)
{
std::cerr << "Error: value cannot be negative\n";
}std::clog
std::clog is commonly used for logging or diagnostic messages.
The distinction between cout, cerr, and clog is primarily about their intended roles and buffering behavior. A simple model is: std::cout for normal program output; std::cerr for errors/diagnostics; std::clog for logging/diagnostics.
std::clog << "Program started\n";Stream Formatting
C++ streams provide many formatting facilities.
Output: 123.46 <iomanip> provides formatting manipulators such as std::setw, std::setprecision, std::fixed, std::scientific, std::left, std::right, and std::setfill.
#include <iostream>
#include <iomanip>
int main()
{
double value = 123.456789;
std::cout << std::fixed
<< std::setprecision(2)
<< value;
return 0;
}std::setprecision
std::setprecision controls floating-point precision.
Without std::fixed, precision generally refers to the number of significant digits.
With std::fixed, the precision specifies digits after the decimal point.
#include <iostream>
#include <iomanip>
int main()
{
double value = 3.1415926535;
std::cout << std::setprecision(4)
<< value;
return 0;
}std::cout << std::fixed
<< std::setprecision(2)
<< value;std::setw
std::setw specifies a minimum field width for the next formatted output operation.
Conceptually the output is right-aligned within a 10-character field: " 123". The field width applies to the next formatted insertion.
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setw(10) << 123;
return 0;
}std::setfill
std::setfill specifies the character used to fill unused field width.
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setfill('0')
<< std::setw(5)
<< 42;
return 0;
}std::left and std::right
These manipulators control alignment.
They are useful when producing formatted tables.
std::cout << std::left
<< std::setw(10)
<< "C++";
std::cout << std::right
<< std::setw(10)
<< "C++";Number Bases
C++ streams can display integers using different bases.
Possible output: 255, ff, 377
int value = 255;
std::cout << std::dec << value << '\n';
std::cout << std::hex << value << '\n';
std::cout << std::oct << value << '\n';Boolean Formatting
std::cout << true; // typically produces 1
std::cout << std::boolalpha << true; // produces trueCharacter Input
A single character can be read using:
Formatted extraction generally skips leading whitespace.
char c;
std::cin >> c;char grade;
std::cin >> grade;
std::cout << "Grade: " << grade << '\n';std::cin.get()
get() can read a character directly from the input stream.
The int form is useful because it can represent every possible character value as well as EOF.
char c;
std::cin.get(c);int c2 = std::cin.get();std::cin.getline()
For character arrays, streams provide:
For modern C++ code, std::string with std::getline(std::cin, name); is generally more convenient.
std::cin.getline(buffer, size);char name[50];
std::cin.getline(name, 50);
std::cout << name;Output Formatting Example
#include <iostream>
#include <iomanip>
#include <string>
int main()
{
std::string name = "Rina";
double score = 95.6789;
std::cout << "Name: " << name << '\n';
std::cout << "Score: "
<< std::fixed
<< std::setprecision(2)
<< score
<< '\n';
return 0;
}Name: Rina
Score: 95.68A Complete Input/Output Example
This example demonstrates std::cin, std::cout, std::cerr, std::getline, input validation, stream state checking, input-buffer handling, and floating-point formatting.
Prompt for and read age with std::cin, checking for failure immediately.
Discard the leftover newline with std::cin.ignore so getline does not read an empty line.
Prompt for and read the full name with std::getline, which allows spaces.
Prompt for and read salary with std::cin, again checking for failure.
Print a formatted summary, using std::fixed and std::setprecision(2) for the salary.
#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
int main()
{
std::string name;
int age;
double salary;
std::cout << "Enter age: ";
std::cin >> age;
if (std::cin.fail())
{
std::cerr << "Invalid age\n";
return 1;
}
std::cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'\n'
);
std::cout << "Enter name: ";
std::getline(std::cin, name);
std::cout << "Enter salary: ";
std::cin >> salary;
if (std::cin.fail())
{
std::cerr << "Invalid salary\n";
return 1;
}
std::cout << "\n--- Information ---\n";
std::cout << "Name: " << name << '\n';
std::cout << "Age: " << age << '\n';
std::cout << "Salary: "
<< std::fixed
<< std::setprecision(2)
<< salary << '\n';
return 0;
}Best Practices
1. Prefer '\n' for ordinary newlines:
2. Use std::getline for complete text lines:
3. Validate important input:
4. Use formatting deliberately:
5. Use std::cerr for error messages:
6. Understand stream state. Know the difference between std::cin.clear(); and std::cin.ignore(...);
7. Avoid unsafe assumptions about user input. Input should be treated as potentially invalid.
std::cout << "Done\n";std::getline(std::cin, name);if (!(std::cin >> value))
{
// Handle invalid input
}std::cout << std::fixed
<< std::setprecision(2)
<< value;std::cerr << "Invalid input\n";Quick Reference
Output: std::cout << value;
Input: std::cin >> value;
Full line: std::getline(std::cin, text);
Error output: std::cerr << "Error\n";
Logging: std::clog << "Log message\n";
New line: std::cout << '\n';// Floating-point formatting
std::cout << std::fixed
<< std::setprecision(2)
<< value;
// Check input
if (std::cin)
{
// Input succeeded
}
// Check failure
if (std::cin.fail())
{
// Input failed
}
// Clear failure state
std::cin.clear();
// Discard remaining input
std::cin.ignore(
std::numeric_limits<std::streamsize>::max(),
'\n'
);C++ I/O Mental Model
For formatted input: User enters data → std::cin → operator >> → type conversion/parsing → program object.
For output: Program value → std::cout → operator << → formatting → output destination.
Why does std::cin >> name; only capture "Rina" when the user types "Rina Sahu", and what should be used instead to capture the whole line?
The extraction operator >> stops reading as soon as it hits whitespace, so it only captures the first token, "Rina". To read the entire line, including spaces, use std::getline(std::cin, name); instead.
After std::cin >> age; is followed directly by std::getline(std::cin, name);, why might name end up empty, and how do you fix it?
The formatted extraction (>>) leaves the trailing newline character in the input buffer. The very next std::getline call immediately reads that leftover newline as an empty line. The fix is to discard it first with std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before calling std::getline.
What is the difference in effect between std::cin.clear() and std::cin.ignore(...) after an input failure?
std::cin.clear() resets the stream's error flags (like failbit) so it can be used again, but it does not remove the bad characters still sitting in the input buffer. std::cin.ignore(...) discards characters from the buffer (up to a count or a delimiter). Typically both are needed together: clear() to reset the stream state, then ignore(...) to discard the invalid leftover input.
What does std::setprecision(2) mean when combined with std::fixed versus when used alone?
Combined with std::fixed, setprecision(2) fixes the number of digits after the decimal point to 2 (e.g. 95.6789 becomes 95.68). Used alone (without std::fixed), setprecision(2) instead limits the total number of significant digits shown.
What is the practical difference between std::cout, std::cerr, and std::clog, given that all three can print text to the terminal?
They are distinguished by intended role and buffering: std::cout is for normal program output, std::cerr is for error/diagnostic messages, and std::clog is for logging/diagnostic messages. std::cerr is typically unbuffered so error messages appear immediately, while std::cout and std::clog may be buffered.
What does this program print?
It prints 00042. std::setw(5) reserves a minimum field width of 5 characters for the next output, and std::setfill('0') makes the padding character '0' instead of the default space, right-aligning 42 within that width.
This snippet mixes signed/unsigned comparison with stream state checking. If a valid integer is entered, what does std::cin >> a evaluate to inside the condition, and why can result end up false even though -1 is mathematically less than 1?
std::cin >> a evaluates (in a boolean context) to whether the extraction succeeded, so on valid input it is truthy. However, a < b compares a signed int to an unsigned int, so a is converted to unsigned before comparing; -1 becomes a very large unsigned value, making a < b false, so result is false despite -1 being mathematically smaller than 1.
Write a program that reads a person's age (int) and full name (a line, possibly containing spaces) safely, validating the age and correctly handling the leftover newline before reading the name.
The program checks std::cin.fail() right after reading age to catch invalid numeric input, then uses std::cin.ignore(...) to discard the leftover newline before calling std::getline, so the full name (including spaces) is read correctly rather than coming out empty.
Write a program that prints a small right-aligned table of two rows, each showing a name and a score formatted to 2 decimal places, using std::setw, std::left/std::right, and std::fixed/std::setprecision.
std::left with std::setw(10) left-aligns each name within a 10-character field, while std::right with std::setw(8) right-aligns each score within an 8-character field; std::fixed combined with std::setprecision(2) ensures every score displays with exactly two digits after the decimal point.
C++ Program
│
┌──────────┴──────────┐
│ │
Input Output
│ │
↓ ↓
std::cin std::cout
│ │
↓ ↓
User/Input Screen/Output#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setfill('0') << std::setw(5) << 42;
return 0;
}int a = -1;
unsigned int b = 1;
bool result = (std::cin >> a) && (a < b);