Two tools: stream manipulators from <iomanip> (classic, sticky state) and C++20's std::format (Python-style format strings, type-safe).
std::format (C++20)
#include <format>
#include <iostream>
#include <numbers>
int main() {
std::cout << std::format("{} + {} = {}\n", 2, 3, 2 + 3);
std::cout << std::format("[{:>6}] [{:<6}] [{:^6}]\n", "r", "l", "c"); // align in width 6
std::cout << std::format("{:.3f} {:e}\n", std::numbers::pi, 12345.678);
std::cout << std::format("{:05d} {:+d} {:#x} {:#b}\n", 42, 7, 255, 5);
std::cout << std::format("{1} {0} {1}\n", "a", "b"); // positional
std::cout << std::format("{:*^11}\n", " hi "); // custom fill
}2 + 3 = 5
[ r] [l ] [ c ]
3.142 1.234568e+04
00042 +7 0xff 0b101
b a b
*** hi ****| Spec | Meaning | Example → result |
|---|---|---|
{:>8} {:<8} {:^8} | Right / left / centre in width 8 | {:>4}, 7 → 7 |
{:*^8} | Centre with fill character * | {:*^5}, "a" → **a** |
{:.2f} | Fixed, 2 decimals | 3.14159 → 3.14 |
{:e} / {:g} | Scientific / shortest | 1500.0 → 1.500000e+03 / 1500 |
{:05d} | Zero-pad to width 5 | 42 → 00042 |
{:x} {:#x} {:b} {:o} | Hex, hex with 0x, binary, octal | 255 → ff, 0xff |
{:+} | Always show sign | 7 → +7 |
Stream manipulators (<iomanip>)
#include <iomanip>
#include <iostream>
int main() {
double price = 3.14159;
std::cout << std::fixed << std::setprecision(2) << price << '\n';
std::cout << price * 2 << '\n'; // precision is *sticky*
std::cout << std::setw(6) << 42 << '|' << 42 << '|' << '\n'; // setw applies to next item only
std::cout << std::setfill('0') << std::setw(4) << 7 << '\n';
std::cout << std::left << std::setfill('.') << std::setw(8) << "name" << "Ada\n";
std::cout << std::hex << 255 << ' ' << std::dec << 255 << '\n';
std::cout << std::boolalpha << true << ' ' << std::noboolalpha << true << '\n';
}3.14
6.28
42|42|
0007
name....Ada
ff 255
true 1| Manipulator | Effect | Sticky? |
|---|---|---|
std::setw(n) | Minimum width of the next field | No — next output only |
std::setprecision(n) | Significant digits (or decimals with fixed) | Yes |
std::fixed / std::scientific | Floating-point notation | Yes |
std::setfill(c) | Padding character | Yes |
std::left / std::right | Alignment inside the width | Yes |
std::hex / std::oct / std::dec | Integer base | Yes |
std::boolalpha | Print true/false instead of 1/0 | Yes |
What does std::setprecision(3) do without std::fixed?