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 19 – C++ for DSA and competitive programming

Fast C++ input and output for online judges

Why C++ streams read slowly as they start, the two lines that fix it, why std::endl in a loop costs a flush per line, and when an interactive problem needs one.

  • Beginner
  • 20 minutes
  • Examples run with Clang 21.0.0, GCC 16.2.0 and Python 3.14.8
  • By MySmartCoPilot
Free core, Pro depth: 8 of 20 minutes free
Free: Two defaults make cin slow as it starts · Two lines make GCC's cin about twenty times faster · std::endl flushes every line, a newline does not · 2 more sections. With a pass: 2 in-depth parts and 3 interview answers, about 12 minutes.

What you will learn

  • Configure the C++ streams for fast input without breaking them
  • Avoid a flush per line in output loops
  • Handle interactive problems by flushing after every query
  • Choose a reader and a writer from measurements on both standard libraries

Before you start

Fast C++ input on a judge comes down to two lines at the start of main: std::ios::sync_with_stdio(false); and std::cin.tie(nullptr);. In the measured run below, the two lines made GCC’s cin read a million integers about twenty times faster. As the streams start, every read through cin is kept in step with C’s scanf and getchar, and it first flush: To force the text a stream is holding in its buffer out to the screen or the file at once. std::endl flushes after its line break; '\n' alone does not, so the stream can write many lines together. More in “Console I/O in C++: cin, cout, print and println” cout, because the two streams are tied. The first line lets the C++ streams buffer on their own; the second removes the flush.

Output for online judges has a rule of its own: end lines with '\n', not std::endl, which also flushes the stream on every line. A problem in which the judge's program talks to yours while it runs: it reads each query your program prints, answers it, and waits for the next one, instead of giving all of the input at the start. are the one exception to both rules: the judge waits for each of your queries before it answers, so there you flush after every query.

Two defaults make cin slow as it starts

The C++ standard makes cin, cout and the other standard streams: The three channels a console program starts with: standard input, which std::cin reads, and standard output and standard error, which std::cout and std::cerr write. The shell can connect each one to the terminal, a file or a pipe. More in “Console I/O in C++: cin, cout, print and println” work together with C’s stdin and stdout unless a program says otherwise. A program can then mix std::cin >> x with scanf and see the input in the right order, because each C++ operation goes straight through to the C stream. That safety costs speed: cppreference notes that the synchronised streams are, in practice, unbuffered.

The second cost is the tie. The standard says that after cin is set up, cin.tie() returns &cout, and before any read, a stream flushes the stream it is tied to. That is what makes a prompt such as “Enter n:” appear before the program waits for you, and it means a program that reads a number and prints a line, a million times, also flushes cout a million times.

One cin read as the streams start (flush cout, then go through C stdin) and after the two lines (no flush, own buffer).As the streams startAfter the two linescin >> xflush cout first:cin is tied to couttake characters throughC's stdin, in stepwith scanf and getcharcin >> xno flush:cin.tie(nullptr)parse from cin's ownbuffer, refilled inlarge blocks

What one read with cin does before and after the two template lines, in libstdc++

Text description of the diagram

Two columns show the steps of one read, cin >> x.

As the streams start: first cout is flushed, because cin is tied to cout; then the characters are taken through C's standard input, kept in step with scanf and getchar, so that C and C++ input can be mixed.

After the two lines, std::ios::sync_with_stdio(false) and std::cin.tie(nullptr): there is no flush before the read, and the number is parsed from cin's own buffer, which is refilled from the input in large blocks.

In libc++, the library of Apple clang, cin stayed slow after the two lines in the version measured here.

The left column is the path of every read as the streams start, and the right column the path after the two lines that the next section measures.

Checkpoint

Check: Why cin starts slow

  1. Question 1 of 2 A program prints "Enter n:" with cout and then reads n with cin. Why does the prompt appear before the program waits for you?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: cin is tied to cout, so before the read it flushes cout

    The tie is the reason a prompt shows up in time. It also means that a program which reads a number and prints a line, a million times, flushes cout a million times.

  2. Question 2 of 2 As the streams start, what does keeping cin in step with C's stdin let a program do?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Mix std::cin >> x with scanf and getchar and still see the input in the right order

    The standard makes the C++ streams work together with C's stdin and stdout unless a program says otherwise. That safety costs speed: cppreference notes that the synchronised streams are, in practice, unbuffered.

Two lines make GCC’s cin about twenty times faster

This program reads a million integers in three ways and reports the CPU time each took, which other programs on the computer hardly change. Every time on this page was measured on an Apple M5 Pro under macOS 26:

read_three_ways.cpp C++ · read_three_ways.cpp
// read_three_ways.cpp: reads n integers and prints their sum and the CPU time it took, in one of three ways:
//   ./read default   std::cin as the streams start
//   ./read tuned     std::cin after the two lines of a contest template
//   ./read scanf     C's scanf
#include <cstdio>
#include <ctime>
#include <iostream>
#include <string_view>

int main(int argc, char* argv[]) {
    const std::string_view how = argc > 1 ? argv[1] : "default";
    if (how == "tuned") {
        std::ios::sync_with_stdio(false);  // C++ streams may buffer on their own, apart from C's stdio
        std::cin.tie(nullptr);             // reading no longer flushes cout first
    }
    const std::clock_t start = std::clock();  // CPU time, which other programs hardly change
    long long n = 0, sum = 0;
    if (how == "scanf") {
        if (std::scanf("%lld", &n) != 1) return 1;
        for (long long i = 0, x = 0; i < n && std::scanf("%lld", &x) == 1; ++i) sum += x;
    } else {
        std::cin >> n;
        for (long long i = 0, x = 0; i < n && std::cin >> x; ++i) sum += x;
    }
    const double ms = 1000.0 * static_cast<double>(std::clock() - start) / CLOCKS_PER_SEC;
    std::printf("%-7s %lld numbers, sum %lld, %5.0f ms\n", how.data(), n, sum, ms);
}
A million integers, three readers, two libraries Python · three_ways_session.py
from session import run

# A million integers read three ways with each standard library: Apple clang uses libc++, GCC uses libstdc++.
run("""
python3 gen_ints.py
clang++ -std=c++23 -O2 read_three_ways.cpp -o read && ./read default < ints.txt && ./read tuned < ints.txt && ./read scanf < ints.txt
g++-16 -std=c++23 -O2 read_three_ways.cpp -o read-gcc && ./read-gcc default < ints.txt && ./read-gcc tuned < ints.txt && ./read-gcc scanf < ints.txt
""")

Output

$ python3 gen_ints.py
wrote ints.txt: 1000000 numbers, sum 260585712848
$ clang++ -std=c++23 -O2 read_three_ways.cpp -o read && ./read default < ints.txt && ./read tuned < ints.txt && ./read scanf < ints.txt
default 1000000 numbers, sum 260585712848,  1668 ms
tuned   1000000 numbers, sum 260585712848,  1625 ms
scanf   1000000 numbers, sum 260585712848,   107 ms
$ g++-16 -std=c++23 -O2 read_three_ways.cpp -o read-gcc && ./read-gcc default < ints.txt && ./read-gcc tuned < ints.txt && ./read-gcc scanf < ints.txt
default 1000000 numbers, sum 260585712848,  1279 ms
tuned   1000000 numbers, sum 260585712848,    64 ms
scanf   1000000 numbers, sum 260585712848,   114 ms

This output changes from run to run: CPU times change a little from run to run and a lot 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 three_ways_session.py

With GCC’s libstdc++, the library of every GCC-based judge, the two lines took cin from more than a second to well under a tenth of one, and scanf was fast too. Apple clang’s libc++ is the exception: its cin stayed slow with the two lines, while scanf was as fast there as with GCC. Fast C++ input on a GCC judge therefore needs nothing more than the two lines. Keep them in your template, and when you work on a Mac, measure your reading code with GCC, or read with scanf, before you decide that a solution is too slow.

The two lines come with one rule: once the streams are no longer in step, do not mix C and C++ output on the same stream, or C and C++ input. Call both lines before any input or output: if sync_with_stdio comes after the first read or write, the standard leaves its effect to each library. This program breaks the rule on purpose:

mixed.cpp C++ · mixed.cpp
// mixed.cpp: after sync_with_stdio(false), cout and printf have separate buffers, so lines can leave out of order.
#include <cstdio>
#include <iostream>

int main() {
    std::ios::sync_with_stdio(false);
    std::cout << "1: cout\n";
    std::printf("2: printf\n");
    std::cout << "3: cout\n";
    std::printf("4: printf\n");
}
The output of mixed.cpp with each library, written to a file Python · mixed_session.py
from session import run

# mixed.cpp with each library, its output written to a file as a judge would, then shown.
run("""
clang++ -std=c++23 -O2 mixed.cpp -o mixed && ./mixed > out.txt && cat out.txt
g++-16 -std=c++23 -O2 mixed.cpp -o mixed-gcc && ./mixed-gcc > out-gcc.txt && cat out-gcc.txt
""")

Output

$ clang++ -std=c++23 -O2 mixed.cpp -o mixed && ./mixed > out.txt && cat out.txt
1: cout
2: printf
3: cout
4: printf
$ g++-16 -std=c++23 -O2 mixed.cpp -o mixed-gcc && ./mixed-gcc > out-gcc.txt && cat out-gcc.txt
1: cout
3: cout
2: printf
4: printf

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

With libstdc++, the four lines left the program as 1, 3, 2, 4: each stream wrote its own buffer when the program ended, cout’s first. libc++ kept the order here, and code that relies on that works with one library only.

Key idea

Put both lines before any input or output, then never mix cin with scanf, or cout with printf.

Checkpoint

Check: What the two template lines change

  1. Question 1 of 3 With GCC 16, reading a million integers with cin took 1279 ms as the streams start and 64 ms after the two lines. About how many times faster is that?

    Type a number.

    Show the answer: Question 1 of 3

    Answer: 20 times (anything from 19 to 21 counts)

    1279 ÷ 64 is about 20: the two lines made libstdc++'s cin about twenty times faster, and faster than its scanf, which took 114 ms.

  2. Question 2 of 3 In the recorded run, which reader stayed slow even after the two lines?

    Choose one answer.

    Show the answer: Question 2 of 3

    Answer: cin with Apple clang's libc++, at 1625 ms

    Fast C++ input on a GCC judge needs nothing more than the two lines. On a Mac, measure with GCC, or read with scanf, before you decide that a solution is too slow.

  3. Question 3 of 3 A program reads the first number with cin and only then calls std::ios::sync_with_stdio(false). What can you rely on?

    Choose one answer.

    A hint

    The lesson names one rule about when the call must come.

    Show the answer: Question 3 of 3

    Answer: Nothing in particular; the standard leaves the effect of a late call to each library

    The two lines come with one rule each way: call them before any input or output, and once the streams are no longer in step, never mix C and C++ output on one stream, or C and C++ input.

std::endl flushes every line, a newline does not

std::endl writes a newline and then flushes the stream, and a flush hands the buffer to the operating system, which costs far more than storing one character. In a loop that prints a million lines, that is a million separate writes. '\n' only stores the newline; the stream is flushed when its buffer fills and when the program ends normally, so nothing is lost. Output for online judges should therefore use '\n', or printf, which is buffered too when its output goes to a file.

Step through the same loop both ways, and count the writes that reach the file:

Interactive · step by step Where a line goes with a newline, and with std::endl Step through an output loop that prints a million lines. The left column is your program and cout's buffer; the right column is the file or pipe the judge reads.
Where a line goes with a newline, and with std::endl, step 6 of 6. Showing the output loop, cout's buffer (empty after every line), the file or pipe (a million writes). In focus: the file or pipe.a writethe output loopa million linescout's bufferempty after every linethe file or pipea million writes

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. A newline is stored. With '\n', each line is stored in cout's buffer. Storing one more character costs almost nothing, and nothing reaches the file yet.
  2. Lines pile up. The loop goes on, and the buffer collects line after line. The operating system has not been asked to do anything so far.
  3. One write for many lines. When the buffer is full, the stream hands all of its lines to the operating system in one write, then starts filling the buffer again.
  4. Nothing is lost at the end. When the program ends normally, the stream flushes what is left. So '\n' loses no output; it only decides when the lines are written.
  5. std::endl flushes. std::endl writes the newline and then flushes the stream. Each line goes to the operating system at once, on its own, before the next line is printed.
  6. A million writes. In a loop of a million lines, std::endl makes a million separate writes, and each costs far more than storing a character. Use '\n' unless a line must leave now.

Both loops wrote the same lines; only the number of writes differed, one per line with std::endl and one per full buffer with a newline.

Checkpoint

Check: std::endl against a newline

  1. Question 1 of 2 A loop prints a million lines, each ended with std::endl. How many times does it flush the stream?

    Type a number.

    Show the answer: Question 1 of 2

    Answer: 1000000 flushes

    std::endl writes a newline and then flushes, once per line: a million flushes, each a separate write to the operating system. With '\n' the stream flushes only when its buffer fills and when the program ends.

  2. Question 2 of 2 A solution ends every line with '\n' and never flushes. When main returns normally, what happens to the lines still in the buffer?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The stream flushes them, so nothing is lost

    '\n' decides when lines are written, not whether: the stream writes them when its buffer fills and when the program ends normally. That is why output for online judges should use '\n'.

An interactive judge waits for every query you flush

In an interactive problem the judge reads each query of your program, answers it, and only then expects the next one. A query that is still in your program’s buffer never reaches the judge, so both programs wait for each other until the time limit ends. Flush after every query: std::flush flushes cout without writing anything, std::endl writes a newline and flushes, and fflush(stdout) does the same for printf. Keeping cin tied to cout also works, because every read then flushes the query for you.

Follow the first query of an interactive problem, once without a flush and once with one:

Interactive · message by message A query that waits in the buffer, and the flush that sends it Step through the first query of an interactive problem. Each arrow is one event, in time order.
A query that waits in the buffer, and the flush that sends it, step 6 of 6. Messages so far: your solution to cout's buffer: query 1; cout's buffer to the judge: query 1; the judge to your solution: answer 1.your solutionhas its answercout's bufferemptythe judgehas read query 1query 1query 1answer 1flushed by every read of cin

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The query is stored. Your solution prints its first query with '\n' and no flush. The line goes into cout's buffer, inside your own program, and nothing reaches the judge.
  2. Your program waits. Next the solution reads the judge's answer, so it stops and waits for input.
  3. The judge waits too. The judge answers only a query it has read, and it has read nothing. Both programs wait for each other until the time limit ends the run.
  4. Flush the query. With std::flush after the query, or std::endl, or fflush(stdout) after printf, the buffer is handed over at once, and the judge reads the query.
  5. The answer comes back. The judge answers, and the read in your solution returns with it. Every query needs its flush before the next read.
  6. A tied cin flushes for you. If cin is still tied to cout, every read flushes cout first, so the query leaves before your program waits, without a flush of your own.

Ordinary output wants as few flushes as possible; an interactive query needs its flush every time, or the judge never sees it.

Checkpoint

Check: Flushing in interactive problems

  1. Question 1 of 2 An interactive solution prints a query with '\n', no flush, and then reads the answer. What happens?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The query stays in the buffer, both programs wait for each other, and the run ends at the time limit

    In an interactive problem the judge waits for each query before it answers. Flush after every query, with std::flush, std::endl or fflush(stdout) for printf.

  2. Question 2 of 2 An interactive solution has no flush of its own but works. After you add std::cin.tie(nullptr) it stops getting answers. Why?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The tie was what flushed each query before every read; untying removes that flush

    Keeping cin tied to cout works for interactive problems, because every read flushes the query. Without the tie, write the flush yourself after every query.

Practise: reading, writing and flushing

Test the two defaults, the two template lines, line endings and interactive flushes here. Your least sure idea is asked about first, and every option carries a reason.

Practice that adapts to you

Practise this lesson

9 questions about 7 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 9 What does std::cin.tie(nullptr) change?

    Choose one answer.

    Show the answer: Question 1 of 9

    Answer: cin no longer flushes cout before each read

    cin starts out tied to cout, so every read first flushes cout, which is what lets a prompt appear before you type. Untying removes that flush. The separate buffer comes from the other line, sync_with_stdio(false).

  2. Question 2 of 9 As the streams start, why is every read through cin slow?

    Choose one answer.

    Show the answer: Question 2 of 9

    Answer: Each C++ operation goes straight through to C's stdin, so the synchronised streams are in practice unbuffered, and each read first flushes cout

    Synchronisation keeps C and C++ input in step, at the cost of buffering, and the tie flushes cout before every read. A program that reads a number and prints a line, a million times, pays both a million times.

  3. Question 3 of 9 In the lesson's measured run, which way of reading a million integers was slow with both standard libraries?

    Choose one answer.

    Show the answer: Question 3 of 9

    Answer: std::cin as the streams start

    The default cin took over a second with both libraries. The two lines made it fast with GCC's libstdc++ only; with Apple clang's libc++ it stayed slow, while scanf was fast with both.

  4. Question 4 of 9 A program calls std::ios::sync_with_stdio(false) and then prints with both cout and printf. What can go wrong?

    Choose one answer.

    Show the answer: Question 4 of 9

    Answer: The lines can leave the program in a different order from the one they were written in

    After the call the C++ streams may buffer on their own, apart from C's stdio, so each buffer is written out when it fills or when the program ends. With libstdc++, mixed.cpp printed lines 1 and 3 before lines 2 and 4.

  5. Question 5 of 9 Your solution starts with the two lines, and reading 10^6 numbers takes over a second on your Mac with Apple clang. The judge uses GCC. What do you conclude?

    Choose one answer.

    Show the answer: Question 5 of 9

    Answer: Nothing yet; libc++'s cin stays slow with the two lines, so measure the reading with GCC, or read with scanf, before you change the algorithm

    Fast C++ input on a GCC judge needs nothing more than the two lines. When you work on a Mac, measure your reading code with GCC, or read with scanf, before you decide that a solution is too slow.

  6. Question 6 of 9 Why is std::endl slow in a loop that writes a million lines to a file?

    Choose one answer.

    Show the answer: Question 6 of 9

    Answer: It writes a newline and then flushes the stream, so every line becomes a separate write

    std::endl is a newline followed by std::flush. A flush hands the buffer to the operating system, which costs far more than storing one more character. '\n' only stores the character, and the stream flushes when its buffer fills and when the program ends.

  7. Question 7 of 9 How should a solution to an ordinary, non-interactive problem end its output lines?

    Choose one answer.

    Show the answer: Question 7 of 9

    Answer: With '\n', or printf, which is buffered too when its output goes to a file

    Output for online judges should use '\n', or printf, which is buffered too when its output goes to a file. The one exception is an interactive problem, where each query must leave at once.

  8. Question 8 of 9 In an interactive problem you print a query, then read the judge's answer. What has to happen in between?

    Choose one answer.

    Show the answer: Question 8 of 9

    Answer: The query has to be flushed, so that the judge can read it

    A query that sits in your program's buffer never reaches the judge, so the judge waits for it while your program waits for the answer. Flush after every query, with std::flush, std::endl or fflush(stdout), or keep cin tied to cout so that each read flushes it for you.

  9. Question 9 of 9 A query was just printed with std::cout. Which of these send it to the judge before your program reads the answer? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 9 of 9

    Answer:

    • std::cout << std::flush
    • Keeping cin tied to cout, then reading
    • std::cout << std::endl

    Any flush before the read works: std::flush, std::endl, or the tie, which flushes cout as cin starts to read. fflush(stdout) does the same for queries printed with printf.

Five readers and four writers, measured with both libraries Pro: opens with a Pro, Premium or Ultimate pass

How fast a reader is depends on the standard library, and the fastest ways skip the streams entirely. This part measures five readers on a million integers and four ways to write a million lines, with libc++ and with libstdc++.

In this part:

  • Five readers on the same million integers, measured
  • Why tuned cin stayed slow with libc++, and what to use on a Mac
  • Writing a million lines: std::endl against a newline, measured
  • Choosing a reader and a writer

4 runnable examples (C++, Python) · about 11 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Interactive problems, reproduced with a judge you can run Pro: opens with a Pro, Premium or Ultimate pass

In an interactive problem the judge answers each query only after it has read it, so a query that stays in a buffer stops both programs. This part runs a small judge of the same kind on your computer, reproduces the stall and its two fixes, and ends with a timed drill.

In this part:

  • A judge you can run, and the dialogue it expects
  • The missing flush, reproduced, and the template line that causes it
  • Exercise: a timed drill with two million numbers

1 diagram · 4 runnable examples (C++, C++ (guess.cpp), C++ (guess_lost.cpp), C++ (guess_tied.cpp), Python, Python (check_drill.py), Python (gen_drill.py)) · about 7 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Interview questions

  1. Fresher · Warm-up

    What is the difference between std::endl and '\n', and when does the difference matter?

    Both end the line, but std::endl also flushes the stream: it writes '\n' and then calls flush(), which hands the buffer to the operating system. '\n' only stores the character; the stream is flushed when its buffer is full, when you flush it yourself and when the program ends normally. The difference matters when output goes to a file or a pipe, as it does on a judge: with std::endl, each of a million lines becomes its own write to the operating system, while '\n' lets the stream hand over many lines in one write. For a few lines it does not matter, and in an interactive problem the flush is exactly what you need, though std::flush says so more clearly.

  2. Fresher to mid

    Your O(n log n) solution for n = 10^6 exceeds a 2-second time limit on a GCC judge, and a profile on your Mac shows most of the time inside std::cin. How do you confirm that reading is the problem, and what do you change, with the numbers you expect?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  3. Fresher to mid

    An interactive solution works when you type the judge's answers by hand in a terminal, but on the judge it runs out of time on the first test without the judge seeing a single query. Explain both observations and fix the code.

    Model answer, Pro. First step and follow-ups

  4. Mid to senior

    A problem asks for up to 2 × 10^6 numbers, one per line, under a tight time limit, and the judge uses GCC. Design the output code, estimate what each choice costs, and say what you would measure before submitting.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • Start main with std::ios::sync_with_stdio(false); and std::cin.tie(nullptr); for judges that use libstdc++.
  • After the first line, never mix cin with scanf, or cout with printf.
  • End lines with '\n'; std::endl flushes every time.
  • In an interactive problem, flush after every query.

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.