C++ Output (cout)
In C++, printing information to the screen is done with cout, the standard output stream object defined in the <iostream> header. Almost every C++ program you write will use cout to display results, prompt the user, or debug values, which makes it one of the very first tools you need to master. This lesson explains exactly what cout is, how it works internally, and how to format output correctly.
Overview: What Is cout and How It Works
cout stands for "character output." It is a global object of type std::ostream, declared in the <iostream> header and defined inside the std namespace. By default, cout is connected to the standard output device — normally your terminal or console window. When you send data to cout, you are not printing directly to the screen character by character; you are inserting data into a stream, an abstraction that represents a sequence of characters flowing from your program toward a destination.
Internally, cout is usually buffered. Characters you send to it are first collected into an internal memory buffer rather than being written to the terminal immediately. The buffer is flushed (its contents actually sent to the console) when: the buffer becomes full, the program ends normally, you explicitly request a flush (with std::endl or std::flush), or the stream is tied to another stream that forces a flush (like cin being tied to cout). This buffering exists for performance — writing to a terminal is comparatively slow, so batching characters together and writing them in one chunk is much faster than writing one character at a time.
To send data to cout, you use the stream insertion operator, written as <<. This operator is overloaded in the C++ standard library for every built-in type: int, double, char, bool, std::string, pointers, and more. Each overload knows how to convert that specific type into readable characters and knows how to format it by default. Because the correct overload is chosen by the compiler based on the type of the expression, C++ output is type-safe — unlike C's printf, there is no format string to get wrong, and passing the wrong type simply will not compile (or will silently call a different, still-correct overload) rather than corrupting memory.
Every overload of operator<< returns a reference to the same ostream object it was called on. This is what allows you to chain multiple insertions together in a single statement, like cout << a << b << c; — each << call hands back the stream so the next << can be applied to it.
Syntax
#include <iostream>
using namespace std;
int main() {
std::cout << expression1 << expression2 << std::endl;
}
| Part | Meaning |
|---|---|
#include <iostream> |
Brings in the declaration of cout, cin, and related stream types. Required for any program that uses cout. |
std::cout |
The standard output stream object. The std:: prefix specifies it lives in the standard namespace; you can drop the prefix if you write using namespace std;. |
<< |
The stream insertion operator. Sends the value on its right into the stream on its left. Can be chained repeatedly. |
| expression | Any value with a known operator<< overload: a literal, variable, or the result of a calculation. |
std::endl |
A manipulator that inserts a newline character and flushes the stream buffer. |
; |
Ends the C++ statement. |
Examples
Example 1: Basic Text Output
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!" << endl;
cout << "Welcome to C++ programming." << endl;
return 0;
}
Output:
Hello, World!
Welcome to C++ programming.
Each call to cout << ... << endl; is a separate statement. The string literal is inserted into the stream, and endl both moves the cursor to the next line and flushes the output buffer so the text appears immediately.
Example 2: Printing Variables and Chaining
#include <iostream>
#include <string>
using namespace std;
int main() {
string name = "Ada";
int age = 30;
double salary = 55000.5;
cout << "Name: " << name << "\n";
cout << "Age: " << age << ", Salary: $" << salary << endl;
cout << "Next year age: " << age + 1 << endl;
return 0;
}
Output:
Name: Ada
Age: 30, Salary: $55000.5
Next year age: 31
This example chains several values of different types — a string, an int, a double, and even the result of an expression (age + 1) — into single statements. Notice the two ways of moving to a new line: the escape sequence "\n" and the manipulator endl. Both produce a newline; only endl additionally flushes the buffer.
Example 3: Formatting Numbers with iomanip
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double price = 19.99;
double tax = 1.60;
double total = price + tax;
cout << fixed << setprecision(2);
cout << "Price: $" << price << endl;
cout << "Tax: $" << tax << endl;
cout << "Total: $" << total << endl;
return 0;
}
Output:
Price: $19.99
Tax: $1.60
Total: $21.59
By default, cout prints floating-point numbers with up to six significant digits and trims trailing zeros, which is rarely what you want for money or measurements. The <iomanip> header supplies manipulators like fixed (use fixed-point notation instead of scientific) and setprecision(2) (show exactly two digits after the decimal point). Once set, these flags stay in effect for every subsequent insertion on that stream until changed again.
How cout Works Step by Step
- The compiler resolves each
<<call to theoperator<<overload matching the operand's type at compile time — no runtime format-string parsing occurs. - Each overload converts its argument into a sequence of characters according to the stream's current formatting state (base, precision, field width, fixed/scientific, etc.).
- Those characters are appended to
cout's internal buffer, not sent to the terminal yet. - Because every overload returns a reference to the stream itself, the next
<<in the chain operates on the same object, letting insertions read left to right in one statement. - The buffer is flushed — actually written to the console — when it fills up, when
std::endlorstd::flushis used, or automatically when the program exits normally. - Manipulators like
setprecisionandfixedchange persistent state stored inside the stream object, so they affect every following insertion, not just the next one.
Common Mistakes
Mistake 1: Forgetting the std:: prefix or the using directive
#include <iostream>
using namespace std;
int main() {
cout << "Hi!" << endl;
return 0;
}
This fails to compile with an error like 'cout' was not declared in this scope, because cout lives inside the std namespace and was never imported. Fix it by either qualifying the name or adding a using directive:
#include <iostream>
using namespace std;
int main() {
cout << "Hi!" << endl;
return 0;
}
Mistake 2: Trying to use printf-style format specifiers
Beginners coming from C sometimes write cout << "%d", age; expecting it to behave like printf. This compiles but prints the literal text %d, because cout does not interpret format specifiers at all — it simply prints the string as-is, and the comma operator discards age. The correct approach is to insert the variable directly with <<:
cout << "Age: " << age << endl;
Mistake 3: Overusing std::endl in loops
Writing cout << i << endl; inside a loop that runs thousands of times forces a buffer flush every single iteration, which is far slower than necessary. When you don't need output visible immediately, prefer "\n" and let the buffer flush naturally, reserving endl for points where you genuinely need the output to appear right away (for example, right before reading input).
Best Practices
- Always
#include <iostream>before usingcout. - In small learning programs,
using namespace std;is fine; in larger or multi-file projects, prefer explicitstd::coutto avoid name collisions. - Use
"\n"instead ofstd::endlwhen writing large amounts of output or output inside loops, since it avoids unnecessary buffer flushes. - Chain related insertions into a single statement for readability:
cout << a << b << c;instead of three separate statements. - Use the
<iomanip>manipulators (setprecision,fixed,setw,boolalpha) whenever the default formatting of numbers or booleans is not what you want to display. - Remember that manipulator settings like
fixedandsetprecisionpersist on the stream until changed — set them once rather than repeating them before every insertion. - Don't mix
coutwith C'sprintfin the same program unless you explicitly synchronize the streams; keep output consistent.
Practice Exercises
- Write a program that declares your name, age, and favorite programming language as variables, then prints each one on its own line using
cout. - Write a program that declares two integers, computes their sum, product, and difference, and prints all three results with descriptive labels in a single chained
coutstatement per calculation. - Using
<iomanip>, write a program that prints the value of pi (use3.14159265) rounded to exactly 4 decimal places usingfixedandsetprecision. Expected output:3.1416.
Summary
coutis the standard output stream object, declared in<iostream>and defined in namespacestd.- Data is sent to
coutusing the insertion operator<<, which is type-overloaded and returns a reference to the stream, enabling chaining. - Output is buffered;
std::endlinserts a newline and flushes the buffer, while"\n"inserts a newline without flushing and is faster in tight loops. - Default floating-point formatting shows up to six significant digits; use
<iomanip>manipulators likefixedandsetprecisionfor predictable decimal formatting. coutis type-safe and does not use format strings, unlike C'sprintf.
