C++ cin, getline and cout: Console Input and Output
How cin reads tokens, getline reads lines, and why getline after cin returns an empty string. Reading until end of input, endl vs newline, and fast C++ I/O.
- Course: C++ study plan
- Module: C++ and the toolchain
- Kind: Lesson
- Reading time: 16 min
- Runtime: Clang 18 · C++20
How do you read input in C++?
In C++ you read standard input with std::cin from <iostream>. std::cin >> x skips whitespace and reads one token of x's type, ignoring line boundaries; std::getline(std::cin, line) reads a whole line, spaces included, and discards the newline. while (std::cin >> x) reads until the input ends, because the stream converts to false once a read fails.
Lesson
Every exercise in this track — and every coding-round harness, contest judge and command-line tool — is a program that reads standard input and writes standard output. The C++ streams do this well once you know three facts: >> reads whitespace-separated tokens and skips the whitespace around them; std::getline reads a whole line, spaces included, and consumes the newline; and switching from the first to the second leaves a newline behind that you must throw away. This lesson fixes those facts, the read-until-the-input-ends loops, and the output habits that keep a judged program fast and its output exact.
The three streams
<iostream> declares std::cin (standard input), std::cout (standard output) and std::cerr (standard error). The judge feeds a test case to cin and compares only what you write to cout; cerr is shown to you as diagnostics and never marked wrong, so it is the place for debugging prints.
>> reads tokens
#include <iostream>
int main() {
int n;
std::cin >> n;
long long total = 0;
for (int i = 0; i < n; ++i) {
long long x;
std::cin >> x;
total += x;
}
std::cout << total << '\n';
return 0;
}
std::cin >> x skips any leading whitespace (spaces, tabs, newlines — any amount, across lines), then reads the characters that can belong to a value of x's type and stops at the first that cannot. For an int that is an optional sign and digits; for a std::string, everything up to the next whitespace; for a char, exactly one non-space character. The input 3 10 20 30 and the input 3⏎10⏎20⏎30⏎ read identically, which is why "N then N numbers" never needs to know the line layout. Chains read left to right: std::cin >> name >> age;.
When the next characters cannot form the value (abc into an int), or there are none left, the extraction fails: the stream sets its fail bit, the variable is set to 0, and every later >> does nothing until you std::cin.clear() it. In exercises the input is well-formed, so a failed read means your reading order is wrong, not the input.
std::getline reads lines
#include <iostream>
#include <string>
int main() {
std::string line;
std::getline(std::cin, line);
std::cout << "[" << line << "]\n";
return 0;
}
std::getline(std::cin, line) reads everything up to the next newline into line, discards the newline and returns the stream. Leading spaces are kept, an empty line yields an empty string, and a name with a space in it arrives whole — which >> could never manage. A third argument changes the delimiter: std::getline(stream, field, ',') reads up to the next comma, the basis of every CSV parser (Module 5 lesson 4).
Mixing them: the leftover newline
The most common input bug in C++:
int n;
std::cin >> n; // input "2⏎Ada Lovelace⏎": reads 2, leaves "⏎Ada Lovelace⏎"
std::string name;
std::getline(std::cin, name); // reads up to the first newline: name is "" (empty!)
>> stops at the newline after 2 and leaves it in the buffer; getline meets that newline immediately and returns an empty line. The fix is to discard the rest of the current line before the first getline:
int n;
std::cin >> n;
std::cin.ignore(); // throw away one character: the newline
std::string name;
std::getline(std::cin, name); // "Ada Lovelace"
std::cin.ignore() skips one character. When the line might carry trailing spaces after the number, the robust form is std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); (from <limits>), which skips everything up to and including the next newline. A third form, std::getline(std::cin >> std::ws, name), skips all whitespace first — including empty lines, which is wrong when an empty line is meaningful. The rule: after >>, before getline, ignore the rest of the line.
Reading until the end of input
std::cin >> x returns the stream, and a stream converts to false once a read has failed. That gives the two loops every "read everything" program uses:
long long x;
while (std::cin >> x) { // one token at a time, any layout, until nothing is left
total += x;
}
std::string line;
while (std::getline(std::cin, line)) { // one line at a time, until the input ends
++lines;
}
There is no count to read first and no sentinel to look for: the loop ends when the input does. Do not write while (!std::cin.eof()) — eof() becomes true only after a read has hit the end, so that loop processes the last value twice.
A line, then the tokens inside it
When a line's content is a list of tokens and the line boundary matters, read the line and then treat it as a stream:
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::string line;
while (std::getline(std::cin, line)) {
std::istringstream tokens(line);
std::string word;
int count = 0;
while (tokens >> word) ++count;
std::cout << count << '\n';
}
return 0;
}
std::istringstream (from <sstream>) gives a string the same >> interface as cin, so "how many words on each line" needs no hand parsing. Module 5 lesson 4 builds the full parsing toolkit on this idea.
<< writes
std::cout << a << b << c writes each value in turn — numbers in decimal, bool as 1/0 (std::boolalpha switches to true/false), a char as its character ('A' prints A; int('A') prints 65), a std::string or literal as its text. Nothing is inserted between values: std::cout << 1 << 2 prints 12, and separating spaces are your job.
#include <iomanip>
#include <iostream>
int main() {
double ratio = 200.0 / 3;
std::cout << ratio << '\n'; // 66.6667 (six significant digits)
std::cout << std::fixed << std::setprecision(2) << ratio << '\n'; // 66.67
std::cout << std::setw(8) << 42 << '|' << std::left << std::setw(8) << "ab" << "|\n"; // " 42|ab |"
return 0;
}
Floating-point output must always be pinned with std::fixed and std::setprecision(k) before it is judged; the default format prints six significant digits, drops trailing zeros and switches to scientific notation for large values, none of which a test case can rely on. std::fixed, setprecision and std::left are sticky — set once, they stay; std::setw applies to the next value only. Module 5 lesson 5 covers formatting in full, including std::format.
'\n' versus std::endl
Both end the line. std::endl also flushes the stream — forces the buffered text to be written out now — and a flush is a system call. In a loop printing a hundred thousand lines, std::endl costs a hundred thousand system calls and turns an accepted solution into a timeout. Write '\n'. The stream flushes on its own when its buffer fills and when the program ends, so nothing is lost.
Fast I/O
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
// ... read and write as usual ...
return 0;
}
By default the C++ streams are synchronised with C's stdio, so that printf and std::cout can be mixed, and cin flushes cout before every read. The first line switches the synchronisation off — after it, do not mix scanf/printf with the streams — and the second stops cin flushing cout on every read. Together they make the streams several times faster on large inputs, and they are the first two lines of every contest template (Module 20).
The patterns, in one place
| Input format | Read it with |
|---|---|
| N, then N numbers in any layout | std::cin >> n; then a for of std::cin >> x |
| One line of text with spaces | std::getline(std::cin, line) |
| N, then N lines of text | std::cin >> n; std::cin.ignore(); then N getlines |
| Numbers until the input ends | while (std::cin >> x) |
| Lines until the input ends | while (std::getline(std::cin, line)) |
| A line whose tokens matter | getline, then std::istringstream and >> |
Pitfalls
getlineright after>>returns an empty line.std::cin.ignore()first.std::endlin a loop. Use'\n'.- Unpinned floating-point output. Set
std::fixed << std::setprecision(k)once, before printing. while (!std::cin.eof())processes the last item twice; test the read itself.
Key takeaways
>>reads whitespace-separated tokens and ignores line boundaries;std::getlinereads a whole line and eats the newline.- After
>>, beforegetline:std::cin.ignore(). while (std::cin >> x)andwhile (std::getline(std::cin, line))read until the input ends; never testeof()first.'\n', notstd::endl;std::fixed << std::setprecision(k)for every floating-point value that is judged.std::ios::sync_with_stdio(false); std::cin.tie(nullptr);for big inputs, and no C stdio after it.
Common questions
Why does getline skip input after cin >>?
std::cin >> n stops at the newline after the number and leaves it in the buffer, so the next std::getline reads that empty remainder and returns an empty string. Call std::cin.ignore() before the first getline, or, if the line may carry trailing spaces, ignore with a count of std::numeric_limits<std::streamsize>::max() and the newline as its delimiter.
What is the difference between std::endl and a newline character in C++?
Both end the line, but std::endl also flushes the stream, forcing the buffered text out with a system call. In a loop printing many lines those flushes can turn a fast program into a timeout, so write the newline character instead; the stream still flushes when its buffer fills and when the program ends.
What does ios::sync_with_stdio(false) do?
It switches off the synchronisation between the C++ streams and C's stdio, which makes cin and cout several times faster on large inputs; after it, do not mix scanf or printf with the streams. It is paired with std::cin.tie(nullptr), which stops cin flushing cout before every read.
Why is while (!cin.eof()) wrong?
eof() becomes true only after a read has already hit the end of the input, so the loop runs once more after the last value, its read fails, and the last value is processed twice. Test the read itself instead: while (std::cin >> x) or while (std::getline(std::cin, line)).
How do you print a double with 2 decimal places in C++?
Include <iomanip> and write std::cout << std::fixed << std::setprecision(2) << value;. Both manipulators are sticky, so they apply to every later floating-point value until changed; without them the default format prints six significant digits and may switch to scientific notation.
Exercises
N, then N lines
Read an integer n, then n lines of text (a line may contain spaces and may be empty). Print each line as <i>: <line> with i counting from 1, then a final line chars=<total>, the sum of the lines' lengths.
Input: n (0 or more) on its own line, then n lines. Output: n numbered lines, then chars=<total>.
This is the mixed pattern: std::cin >> n leaves the newline behind, so you must std::cin.ignore() before the first std::getline. Read the lines with std::getline — nothing else keeps the spaces.
Example: input
2
hello world
C++ is fun
→
1: hello world
2: C++ is fun
chars=21Numbers until the input ends
Read integers until the end of input — there is no count and no sentinel — and print count=<n> sum=<s> min=<lo> max=<hi> on one line. If there were no numbers at all, print count=0.
Input: zero or more integers in any layout (any number per line, any number of lines). Each fits in a 32-bit int; their sum may not. Output: one line.
Use while (std::cin >> x) — it is false the moment a read fails, which is how the loop ends at the end of input. Keep the sum in a long long.
Example: input 3 1 4 1 5 → count=5 sum=14 min=1 max=5
In this module: C++ and the toolchain
← Anatomy of a C++ program · Compilers, warnings and reading error messages →