Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

C++  Module 1 – Start here: toolchains, compiling and first programs

Console I/O in C++: cin, cout, print and println

Read numbers and whole lines with std::cin and std::getline, format output with C++23 std::print and std::println, and handle bad input and its end.

  • Beginner
  • 20 minutes
  • Examples run with Clang 21.0.0, GCC 16.2.0 and Python 3.14.8
  • By MySmartCoPilot
Free: 20 minutes

What you will learn

  • Read numbers and whole lines from standard input
  • Format output with std::print and std::println
  • Avoid the getline-after-cin trap and detect bad input

Before you start

What you’ll learn · Before you start

What you will learn

  • Read numbers and whole lines from standard input
  • Format output with std::print and std::println
  • Avoid the getline-after-cin trap and detect bad input

Before you start

On this page

A console program talks through three standard streams: it reads standard input, writes results to standard output and writes problems to standard error. In C++, std::cin reads standard input, std::cout writes standard output and std::cerr writes standard error, all from <iostream>. C++23 adds std::print and std::println in <print>, which write formatted text in one call, the way Python’s f-strings or C’s printf do. Use std::cin >> x to read numbers and words, std::getline to read a whole line, and std::println for output that needs columns or a fixed number of decimals. This lesson also covers the two classic input bugs: the empty line after >>, and input that is not a number.

Standard input flows through std::cin into the program, which writes to standard output and standard error.Keyboard,< file or | pipestd::cin >>std::getlineYour programstd::cout << ...std::print, std::printlnstd::cerr << ...std::println(stderr, ...)Standard outputscreen, > file or | pipeStandard errorscreen or 2> filestandard inputflushes before reading

The three standard streams and the C++ names for them

Text description of the diagram

The diagram runs from top to bottom.

  1. Standard input comes from the keyboard, or from a file or a pipe that the shell connects with < or |. The program reads it with std::cin >> and std::getline.
  2. The program writes its results with std::cout, std::print or std::println, which go to standard output: the screen, or a file or a pipe connected with > or |.
  3. It writes error messages with std::cerr or std::println(stderr, ...), which go to standard error: the screen, or a file connected with 2>.

A dashed arrow from std::cin to std::cout says that std::cin flushes std::cout before it waits for input, so a prompt written with std::cout is always visible first.

Two ways to write output

std::cout << writes each value in turn. std::println takes a format string with {} where the values go, and ends the line for you; std::print does not add the line break:

std::cout, std::println and std::print C++ · two_ways.cpp
#include <iostream>
#include <print>

int main() {
    const int runs = 74;
    const int balls = 51;

    std::cout << "Asha scored " << runs << " off " << balls << " balls\n";
    std::println("Asha scored {} off {} balls", runs, balls);
    std::print("Strike rate: {:.2f}", 100.0 * runs / balls);
    std::print("\n");
}
Built and run with both compilers Python · two_ways_session.py
from session import run

run("""
clang++ -std=c++23 -Wall -Wextra two_ways.cpp -o two_ways && ./two_ways
g++-16 -std=c++23 -Wall -Wextra two_ways.cpp -o two_ways && ./two_ways
""")

Output

$ clang++ -std=c++23 -Wall -Wextra two_ways.cpp -o two_ways && ./two_ways
Asha scored 74 off 51 balls
Asha scored 74 off 51 balls
Strike rate: 145.10
$ g++-16 -std=c++23 -Wall -Wextra two_ways.cpp -o two_ways && ./two_ways
Asha scored 74 off 51 balls
Asha scored 74 off 51 balls
Strike rate: 145.10

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 two_ways_session.py

The first two lines came out the same: Asha scored 74 off 51 balls. The third shows why a format string helps: {:.2f} printed the strike rate as 145.10, with two decimals, in one short expression. With std::cout the same result needs std::fixed and std::setprecision(2) (the second from <iomanip>), and both stay set for every later number.

To end a line, write '\n'. std::endl writes the line break and then flushes the stream, which forces the text out to the screen or the file at once, and that costs time when it happens on every line:

Writing a million lines to a file C++ · endl_cost.cpp
#include <chrono>
#include <fstream>
#include <iostream>

int main() {
    using clock = std::chrono::steady_clock;
    const int lines = 1'000'000;

    auto start = clock::now();
    {
        std::ofstream out("newline.txt");
        for (int i = 0; i < lines; ++i) out << i << '\n';
    }
    auto newline_ms = std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start).count();

    start = clock::now();
    {
        std::ofstream out("endl.txt");
        for (int i = 0; i < lines; ++i) out << i << std::endl;
    }
    auto endl_ms = std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start).count();

    std::cout << "'\\n':      " << newline_ms << " ms\n";
    std::cout << "std::endl: " << endl_ms << " ms\n";
}
One run of each build Python · endl_session.py
from session import run

# Both builds are optimised (-O2); the times differ from run to run.
run("""
clang++ -std=c++23 -O2 endl_cost.cpp -o endl_cost && ./endl_cost
g++-16 -std=c++23 -O2 endl_cost.cpp -o endl_cost && ./endl_cost
""")

Output

$ clang++ -std=c++23 -O2 endl_cost.cpp -o endl_cost && ./endl_cost
'\n':      114 ms
std::endl: 5296 ms
$ g++-16 -std=c++23 -O2 endl_cost.cpp -o endl_cost && ./endl_cost
'\n':      79 ms
std::endl: 5097 ms

This output changes from run to run: the times differ from run to run and from one computer to another

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 endl_session.py

Over repeated runs on this track’s build machine, an Apple M5 Pro, the million lines took 40 to 80 ms with '\n' and 1.6 to 4.5 seconds with std::endl, 30 to 60 times as long, with both compilers. Flush only when the text must appear right now, such as a progress message, and use '\n' everywhere else.

Formatting with std::println

A replacement field {} takes the next value; what goes after a colon inside it, the format specification, sets its width, alignment, precision and base:

Width, alignment, precision and base C++ · format_specs.cpp
#include <print>

int main() {
    const double pi = 3.14159265;
    std::println("[{}]", pi);
    std::println("[{:.2f}]", pi);
    std::println("[{:8.3f}]", pi);
    std::println("[{:<8}] [{:>8}] [{:^8}]", "left", "right", "centre");
    std::println("[{:*^12}]", "four");
    std::println("[{:+d}] [{:05d}] [{:#x}] [{:b}]", 42, 42, 255, 5);
    std::println("{0} and {1}, then {0} again", "first", "second");
}
What each field printed Python · format_session.py
from session import run

run("""
clang++ -std=c++23 -Wall -Wextra format_specs.cpp -o format_specs && ./format_specs
g++-16 -std=c++23 -Wall -Wextra format_specs.cpp -o format_specs && ./format_specs
""")

Output

$ clang++ -std=c++23 -Wall -Wextra format_specs.cpp -o format_specs && ./format_specs
[3.14159265]
[3.14]
[   3.142]
[left    ] [   right] [ centre ]
[****four****]
[+42] [00042] [0xff] [101]
first and second, then first again
$ g++-16 -std=c++23 -Wall -Wextra format_specs.cpp -o format_specs && ./format_specs
[3.14159265]
[3.14]
[   3.142]
[left    ] [   right] [ centre ]
[****four****]
[+42] [00042] [0xff] [101]
first and second, then first again

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 format_session.py

Field Printed (between the brackets) What it does
{} [3.14159265] The value in its shortest exact form
{:.2f} [3.14] Two digits after the decimal point
{:8.3f} [ 3.142] At least 8 characters wide; numbers are right-aligned
{:<8}, {:>8}, {:^8} [left ], [ right], [ centre ] Left, right or centre within 8 characters
{:*^12} [****four****] Centred, padded with * instead of spaces
{:+d}, {:05d} [+42], [00042] Always show the sign; pad with zeros to 5 digits
{:#x}, {:b} [0xff], [101] Hexadecimal with its prefix; binary
{0}, {1} first and second, then first again Values by position, so one can be used twice

Widths are what make tables line up. This scorecard sets each column’s width once, in the format string:

An aligned batting scorecard C++ · scorecard.cpp
#include <print>
#include <string>
#include <vector>

struct Innings {
    std::string batter;
    int runs;
    int balls;
    int fours;
    int sixes;
};

int main() {
    const std::vector<Innings> card{
        {"Asha", 74, 51, 8, 2},
        {"Ravi", 9, 14, 1, 0},
        {"Meera", 103, 88, 11, 3},
        {"Kabir", 0, 2, 0, 0},
        {"Zoya", 28, 19, 2, 2},
    };

    std::println("{:<8}{:>5}{:>6}{:>4}{:>4}{:>8}", "Batter", "R", "B", "4s", "6s", "SR");
    int total = 0;
    for (const auto& in : card) {
        const double strike_rate = 100.0 * in.runs / in.balls;
        std::println("{:<8}{:>5}{:>6}{:>4}{:>4}{:>8.2f}", in.batter, in.runs, in.balls, in.fours, in.sixes, strike_rate);
        total += in.runs;
    }
    std::print("{:-<35}\n", "");
    std::println("{:<8}{:>5}", "Total", total);
}
The scorecard, from both builds Python · scorecard_session.py
from session import run

run("""
clang++ -std=c++23 -Wall -Wextra scorecard.cpp -o scorecard && ./scorecard
g++-16 -std=c++23 -Wall -Wextra scorecard.cpp -o scorecard && ./scorecard
""")

Output

$ clang++ -std=c++23 -Wall -Wextra scorecard.cpp -o scorecard && ./scorecard
Batter      R     B  4s  6s      SR
Asha       74    51   8   2  145.10
Ravi        9    14   1   0   64.29
Meera     103    88  11   3  117.05
Kabir       0     2   0   0    0.00
Zoya       28    19   2   2  147.37
-----------------------------------
Total     214
$ g++-16 -std=c++23 -Wall -Wextra scorecard.cpp -o scorecard && ./scorecard
Batter      R     B  4s  6s      SR
Asha       74    51   8   2  145.10
Ravi        9    14   1   0   64.29
Meera     103    88  11   3  117.05
Kabir       0     2   0   0    0.00
Zoya       28    19   2   2  147.37
-----------------------------------
Total     214

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 scorecard_session.py

The batter’s name is left-aligned in 8 characters ({:<8}) and every number is right-aligned in its own column, so the strike rates 145.10, 64.29, 117.05, 0.00 and 147.37 end in the same column. The line of dashes is {:-<35} with an empty value: 35 characters of fill. If a value is wider than its field, it is printed in full and pushes the rest of the line to the right, so choose widths for the longest value you expect.

Text beyond English on Windows

std::print writes to the console through the operating system’s Unicode interface when the program’s text is UTF-8, so characters such as é or € and text in scripts such as Devanagari or Tamil appear correctly in the Windows console, which output through std::cout often does not. With Microsoft’s compiler, build with /utf-8 so that the program’s string literals are UTF-8 (/utf-8 sets both the source and the execution character set). Most macOS and Linux terminals use UTF-8 already.

Reading values with std::cin

std::cin >> x skips any spaces, tabs and line breaks, then reads as many characters as fit the type of x: digits for an int, one word for a std::string. Several reads can be chained (std::cin >> a >> b), and it makes no difference whether the values are on one line or several. Used as a condition, a read is true while it succeeds, so a loop can read everything up to the end of the input:

Reading numbers until the input ends C++ · sum_runs.cpp
#include <iostream>
#include <print>

int main() {
    int runs = 0;
    int total = 0;
    int balls = 0;
    while (std::cin >> runs) {
        total += runs;
        ++balls;
    }
    std::println("{} runs off {} balls", total, balls);
}
Six balls from a file Python · sum_runs_session.py
from session import run

run("""
cat over.txt
clang++ -std=c++23 -Wall -Wextra sum_runs.cpp -o sum_runs && ./sum_runs < over.txt
g++-16 -std=c++23 -Wall -Wextra sum_runs.cpp -o sum_runs && ./sum_runs < over.txt
""")

Output

$ cat over.txt
1 4 0
6 2
1
$ clang++ -std=c++23 -Wall -Wextra sum_runs.cpp -o sum_runs && ./sum_runs < over.txt
14 runs off 6 balls
$ g++-16 -std=c++23 -Wall -Wextra sum_runs.cpp -o sum_runs && ./sum_runs < over.txt
14 runs off 6 balls

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 sum_runs_session.py

The input 1 4 0, 6 2 and 1 spread over three lines gave 14 runs off 6 balls. The loop stops at the end of the input, and it would also stop at the first word that is not a number. To end input typed at the keyboard, press Ctrl-D (macOS and Linux) or Ctrl-Z and then Enter (Windows). To give a program a file as its input, as online judges do, run ./sum_runs < over.txt.

Reading a whole line: the getline trap

std::getline(std::cin, line) reads everything up to the next line break, spaces included, and removes the line break. That is how to read a full name. Mixed with >>, though, it fails in a way that surprises almost everyone:

Age, then full name C++ · age_then_name.cpp
#include <iostream>
#include <string>

int main() {
    int age = 0;
    std::string name;

    std::cout << "Age: ";
    std::cin >> age;
    std::cout << "Full name: ";
    std::getline(std::cin, name);

    std::cout << "\nHello, [" << name << "], age " << age << '\n';
}

The input was 19 on one line and Asha Rao on the next, yet the program printed Hello, [], age 19: an empty name. std::cin >> age read 19 and stopped at the line break after it, leaving that line break waiting. std::getline then read up to the first line break, which came straight away, and returned an empty line. The square brackets in the output are there to make the empty string visible.

The fix is to skip the leftover whitespace before getline. std::ws does exactly that:

std::ws skips the leftover line break C++ · age_then_name_fixed.cpp
#include <iostream>
#include <string>

int main() {
    int age = 0;
    std::string name;

    std::cout << "Age: ";
    std::cin >> age;
    std::cout << "Full name: ";
    std::getline(std::cin >> std::ws, name);

    std::cout << "\nHello, [" << name << "], age " << age << '\n';
}
Both programs, both compilers, the same input Python · age_session.py
from session import run

# The same input file for both programs: an age on the first line, a full name on the second.
run("""
cat age_name.txt
clang++ -std=c++23 -Wall -Wextra age_then_name.cpp -o age_then_name && ./age_then_name < age_name.txt
g++-16 -std=c++23 -Wall -Wextra age_then_name.cpp -o age_then_name && ./age_then_name < age_name.txt
clang++ -std=c++23 -Wall -Wextra age_then_name_fixed.cpp -o age_then_name_fixed && ./age_then_name_fixed < age_name.txt
g++-16 -std=c++23 -Wall -Wextra age_then_name_fixed.cpp -o age_then_name_fixed && ./age_then_name_fixed < age_name.txt
""")

Output

$ cat age_name.txt
19
Asha Rao
$ clang++ -std=c++23 -Wall -Wextra age_then_name.cpp -o age_then_name && ./age_then_name < age_name.txt
Age: Full name: 
Hello, [], age 19
$ g++-16 -std=c++23 -Wall -Wextra age_then_name.cpp -o age_then_name && ./age_then_name < age_name.txt
Age: Full name: 
Hello, [], age 19
$ clang++ -std=c++23 -Wall -Wextra age_then_name_fixed.cpp -o age_then_name_fixed && ./age_then_name_fixed < age_name.txt
Age: Full name: 
Hello, [Asha Rao], age 19
$ g++-16 -std=c++23 -Wall -Wextra age_then_name_fixed.cpp -o age_then_name_fixed && ./age_then_name_fixed < age_name.txt
Age: Full name: 
Hello, [Asha Rao], age 19

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 age_session.py

std::getline(std::cin >> std::ws, name) printed Hello, [Asha Rao], age 19. std::ws also skips blank lines and leading spaces, which is right for a name. If spaces at the start of a line matter, use std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); after the >> instead, which throws away only the rest of that one line.

Both programs print Age: Full name: on one line because the input came from a file, so nothing typed was echoed. In a terminal, your typing appears after each prompt. A prompt written with std::cout always shows before the program waits, because std::cin flushes std::cout before every read (the standard ties the two streams together).

Detecting input that is not a number

When std::cin >> overs meets twenty, the read fails: overs is set to 0, the stream is marked as failed, and twenty is left in the input. Every later read fails at once until the program deals with it. This loop asks until it gets a number in range:

Asking until the answer is a valid number C++ · read_overs.cpp
#include <iostream>
#include <limits>
#include <print>

int main() {
    int overs = -1;
    while (true) {
        std::cout << "Overs (1-50): ";
        if (std::cin >> overs && overs >= 1 && overs <= 50) {
            break;
        }
        if (std::cin.eof()) {
            std::println(stderr, "\nThe input ended before a valid number.");
            return 1;
        }
        if (std::cin.fail()) {
            std::println("\nNot a whole number (overs is now {}). Try again.", overs);
            std::cin.clear();
        } else {
            std::println("\n{} is outside 1-50. Try again.", overs);
        }
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    std::println("\nA {}-over match has {} balls per side.", overs, overs * 6);
}
Three answers, then one wrong answer and the end Python · overs_session.py
from session import run

# Built once with each compiler, then given two inputs: three answers, and a single wrong one.
run("""
clang++ -std=c++23 -Wall -Wextra read_overs.cpp -o read_overs && ./read_overs < overs.txt
./read_overs < overs_bad.txt
g++-16 -std=c++23 -Wall -Wextra read_overs.cpp -o read_overs && ./read_overs < overs.txt
./read_overs < overs_bad.txt
""")

Output

$ clang++ -std=c++23 -Wall -Wextra read_overs.cpp -o read_overs && ./read_overs < overs.txt
Overs (1-50): 
Not a whole number (overs is now 0). Try again.
Overs (1-50): 
75 is outside 1-50. Try again.
Overs (1-50): 
A 20-over match has 120 balls per side.
$ ./read_overs < overs_bad.txt
Overs (1-50): 
Not a whole number (overs is now 0). Try again.
Overs (1-50): 
The input ended before a valid number.
[exit status 1]
$ g++-16 -std=c++23 -Wall -Wextra read_overs.cpp -o read_overs && ./read_overs < overs.txt
Overs (1-50): 
Not a whole number (overs is now 0). Try again.
Overs (1-50): 
75 is outside 1-50. Try again.
Overs (1-50): 
A 20-over match has 120 balls per side.
$ ./read_overs < overs_bad.txt
Overs (1-50): 
Not a whole number (overs is now 0). Try again.
Overs (1-50): 
The input ended before a valid number.
[exit status 1]

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 overs_session.py

With the input twenty, 75 and 20, it printed:

  • Not a whole number (overs is now 0). Try again., after which std::cin.clear() removed the failed state and std::cin.ignore(…, '\n') threw away the rest of the bad line;
  • 75 is outside 1-50. Try again.: that read worked, so only the range check failed;
  • A 20-over match has 120 balls per side.

With only ten on standard input, it printed the first message, then the input ended, so it wrote The input ended before a valid number. to standard error and exited with status 1. Two mistakes make such loops hang or spin forever: calling clear() without ignore(), which reads the same bad word again and again, and forgetting the end-of-input check, after which every read fails at once.

Write error messages to standard error, with std::cerr << or std::println(stderr, …), as this program does. They then stay on the screen even when a user saves the normal output with ./read_overs > result.txt, and they never get mixed into results that another program reads.

Exercise: a marks report

Read a count n and then n whole-number marks from standard input, and print their average with two decimals and the highest mark. For the input 5, then 72 85 64 and 91 57 on two more lines, the output must be exactly Average: 73.80 and then Highest: 91, each on its own line. If the input ends early or holds something that is not a number, print a message to standard error and exit with status 1.

Hint: read the count first and check it, then read the marks in a for loop, and divide as double, not as int.

Text Diff Paste your program's output and the expected output to see the exact character that differs, as a judge compares them.

One solution

A marks report with input checks C++ · marks_report.cpp
#include <iostream>
#include <print>

int main() {
    int n = 0;
    if (!(std::cin >> n) || n <= 0) {
        std::println(stderr, "First give how many marks follow (at least 1).");
        return 1;
    }
    int total = 0;
    int highest = 0;
    for (int i = 0; i < n; ++i) {
        int mark = 0;
        if (!(std::cin >> mark)) {
            std::println(stderr, "Expected {} marks, got {}.", n, i);
            return 1;
        }
        total += mark;
        if (i == 0 || mark > highest) {
            highest = mark;
        }
    }
    std::println("Average: {:.2f}", static_cast<double>(total) / n);
    std::println("Highest: {}", highest);
}
Five marks, then an input that ends early Python · marks_session.py
from session import run

run("""
clang++ -std=c++23 -Wall -Wextra -Wpedantic -Wconversion marks_report.cpp -o marks_report && ./marks_report < marks.txt
./marks_report < marks_short.txt
g++-16 -std=c++23 -Wall -Wextra -Wpedantic -Wconversion marks_report.cpp -o marks_report && ./marks_report < marks.txt
./marks_report < marks_short.txt
""")

Output

$ clang++ -std=c++23 -Wall -Wextra -Wpedantic -Wconversion marks_report.cpp -o marks_report && ./marks_report < marks.txt
Average: 73.80
Highest: 91
$ ./marks_report < marks_short.txt
Expected 3 marks, got 2.
[exit status 1]
$ g++-16 -std=c++23 -Wall -Wextra -Wpedantic -Wconversion marks_report.cpp -o marks_report && ./marks_report < marks.txt
Average: 73.80
Highest: 91
$ ./marks_report < marks_short.txt
Expected 3 marks, got 2.
[exit status 1]

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 marks_session.py

It printed Average: 73.80 and Highest: 91. Given 3 and only two marks, it printed Expected 3 marks, got 2. to standard error and exited with status 1.

Check yourself

Check yourself

5 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.

  1. Question 1 of 5 What is the difference between std::println("Total: {}", 5) and std::print("Total: {}", 5)?

    Choose one answer.

    Show the answer to question 1

    Answer: println ends the line after the text; print does not

    Both are C++23 functions from <print> and both use the same format strings. println writes the formatted text followed by a line break; print writes only the text, so the next output continues on the same line.

  2. Question 2 of 5 Which replacement field prints 3.14159 as 3.14?

    Choose one answer.

    Show the answer to question 2

    Answer: {:.2f}

    The precision follows the dot, and f asks for fixed notation, so {:.2f} gives two digits after the decimal point. {:2} only sets a minimum width of 2 characters, and {:.2} without f sets two significant digits, which prints 3.1.

  3. Question 3 of 5 A program reads an age with std::cin >> age and then a name with std::getline(std::cin, name). Why is the name empty?

    Choose one answer.

    Show the answer to question 3

    Answer: The line break after the age is still in the input, and getline reads up to it

    >> stops at the line break after 19 and leaves it waiting. getline then reads until the first line break, which comes at once, and returns an empty line. std::getline(std::cin >> std::ws, name) skips it first.

  4. Question 4 of 5 int overs = -1; and then std::cin >> overs meets the word twenty. What does overs hold afterwards?

    Choose one answer.

    Show the answer to question 4

    Answer: 0, and the stream is marked as failed

    Since C++11 a failed conversion stores zero, and the stream's fail state is set, so later reads fail at once until clear() is called. The lesson's program printed "overs is now 0".

  5. Question 5 of 5 Why did writing a million lines with std::endl take 30 to 60 times as long as with '\n' in the lesson?

    Choose one answer.

    Show the answer to question 5

    Answer: std::endl flushes the stream after every line, forcing a write each time

    std::endl is a line break followed by flush(). Each flush sends the buffered text to the file at once, so a million lines cause a million writes, while '\n' lets the stream collect many lines and write them together.

Interview questions

What is the difference between std::endl and '\n'? (warm-up)

Both end the line. std::endl then also flushes the stream: the standard defines it as writing a newline followed by a call to flush(). Flushing forces the buffered text out to the terminal or the file, which costs a system call, so std::endl in a loop is slow: writing a million lines to a file took 1.6 to 4.5 seconds with std::endl against 40 to 80 ms with '\n' on this track’s build machine. Use '\n' by default and flush deliberately when the text must appear at once, for example a progress line or output that an interactive judge reads before it sends more input. std::cerr flushes after every write anyway, and std::cin flushes std::cout before reading.

Key takeaways

  • std::cin, std::cout and std::cerr (from <iostream>) read standard input and write standard output and standard error; C++23’s std::print and std::println (from <print>) format output in one call.
  • Inside {}, :.2f sets the decimals, :<8, :>8 and :^8 the alignment and width, and :#x and :b the base.
  • Use '\n', not std::endl, to end lines: flushing every line was 30 to 60 times slower when writing a file.
  • std::cin >> x skips whitespace and stops at the first character that does not fit; while (std::cin >> x) reads to the end of the input.
  • After >>, a line break is still waiting: read lines with std::getline(std::cin >> std::ws, line).
  • A failed read sets the value to 0 and the stream to failed; clear() it, ignore() the bad line, and check eof() so the loop cannot spin.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.