<iomanip>
Parameterized stream manipulators for field width, fill character, numeric base, floating-point precision, monetary formatting, and date/time I/O.
<iomanip>since C++98The <iomanip> header provides parameterized stream manipulators β callable objects that modify a stream's formatting state when inserted into or extracted from it, distinguished from the no-argument manipulators (std::left, std::fixed, std::hex, etc.) defined in <ios> and exposed by <iostream>.
Overview
Stream manipulators fall into two families. Non-parameterized manipulators live in <ios> (transitively included by <iostream>) and need no arguments: std::left, std::fixed, std::hex, std::boolalpha, and so on. Parameterized manipulators require <iomanip> and take one or more arguments that configure the effect.
All manipulators are sticky except std::setw. Sticky means the formatting change persists for every subsequent I/O operation on that stream until explicitly reset. std::setw is consumed by exactly one insertion or extraction and must be reissued before each field that needs non-default width. This asymmetry is the root of the most common <iomanip> bugs.
Manipulator inventory
| Manipulator | Since | Sticky | Description |
|---|---|---|---|
setw(n) | C++98 | No | Minimum field width |
setprecision(n) | C++98 | Yes | Floating-point significant digits or decimal places |
setfill(c) | C++98 | Yes | Pad character (default ' ') |
setbase(b) | C++98 | Yes | Numeric base: 8, 10, or 16 |
setiosflags(mask) | C++98 | Yes | OR-sets named format flags |
resetiosflags(mask) | C++98 | Yes | Clears named format flags |
put_money(mon [, intl]) | C++11 | β | Inserts monetary amount using stream locale |
get_money(mon [, intl]) | C++11 | β | Extracts monetary amount using stream locale |
put_time(tm, fmt) | C++11 | β | Inserts std::tm as formatted date/time |
get_time(tm, fmt) | C++11 | β | Parses std::tm from formatted date/time |
quoted(s [, del [, esc]]) | C++14 | β | Round-trips quoted strings through streams |
Syntax
#include <iomanip>Manipulators are used inline with << for output streams and >> for input streams:
std::cout << std::setw(10) << std::setprecision(4) << std::fixed << value;
std::cin >> std::get_time(&t, "%Y-%m-%d"); // C++11Examples
Aligned table output
setw controls column width; setfill fills empty space; setprecision combined with std::fixed (from <ios>) controls decimal places:
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
int main() {
const std::vector<std::pair<std::string, double>> rows = {
{"Widget", 1.50},
{"Gadget", 199.99},
{"Doohickey", 0.75},
};
std::cout << std::left << std::setw(14) << "Item"
<< std::right << std::setw(10) << "Price" << '\n'
<< std::setfill('-') << std::setw(24) << "" << '\n'
<< std::setfill(' '); // reset fill
std::cout << std::fixed << std::setprecision(2); // sticky
for (auto& [name, price] : rows) { // C++17
std::cout << std::left << std::setw(14) << name
<< std::right << std::setw(10) << price << '\n';
}
}
// Item Price
// ------------------------
// Widget 1.50
// Gadget 199.99
// Doohickey 0.75Hexadecimal memory dump
setbase (or std::hex from <ios>) plus setw/setfill produce compact binary-inspection output:
#include <iomanip>
#include <iostream>
#include <cstddef>
#include <span> // C++20
void hex_dump(std::span<const std::byte> data, std::ostream& out) { // C++20
constexpr std::size_t cols = 16;
const auto saved_flags = out.flags();
const auto saved_fill = out.fill();
out << std::hex << std::setfill('0') << std::uppercase;
for (std::size_t i = 0; i < data.size(); i += cols) {
out << std::setw(8) << i << " ";
for (std::size_t j = 0; j < cols; ++j) {
if (i + j < data.size())
out << std::setw(2)
<< static_cast<unsigned>(data[i + j]) << ' ';
else
out << " ";
}
out << '\n';
}
out.flags(saved_flags);
out.fill(saved_fill);
}Monetary output (C++11)
put_money delegates to the std::money_put facet of the stream's imbued locale. The amount must be expressed in the locale's minor currency unit (cents for USD):
#include <iomanip>
#include <iostream>
#include <locale>
int main() {
std::cout.imbue(std::locale("en_US.UTF-8"));
const long double amount = 12345.67L;
std::cout << std::showbase
<< std::put_money(amount * 100) // C++11 β cents
<< '\n'; // $12,345.67
std::cout << std::put_money(amount * 100, true) // C++11 β international
<< '\n'; // USD 12,345.67
}Date/time I/O (C++11)
put_time and get_time wrap std::strftime/std::strptime via the std::time_put/std::time_get locale facets:
#include <iomanip>
#include <iostream>
#include <sstream>
#include <ctime>
int main() {
// Write
std::time_t now = std::time(nullptr);
std::tm* local = std::localtime(&now);
std::cout << std::put_time(local, "%Y-%m-%d %H:%M:%S") << '\n'; // C++11
// Read β always value-initialize; get_time may leave unset fields undefined
std::tm parsed{};
std::istringstream ss("2026-06-15 09:30:00");
ss >> std::get_time(&parsed, "%Y-%m-%d %H:%M:%S"); // C++11
if (ss.fail())
std::cerr << "Parse error\n";
}Quoted strings (C++14)
std::quoted inserts a delimiter (default ") and escapes any occurrences of the delimiter or escape character inside the string. On extraction it strips the delimiters and unescapes:
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
int main() {
const std::string path = R"(C:\Program Files\My "App")";
std::ostringstream out;
out << std::quoted(path); // C++14
std::cout << out.str() << '\n';
// "C:\\Program Files\\My \"App\""
std::string recovered;
std::istringstream in(out.str());
in >> std::quoted(recovered); // C++14
// recovered == path β exact round-trip
}std::quoted is particularly useful for serialising paths or tokens that may contain spaces, since unquoted operator>> stops at whitespace.
Best Practices
Capture and restore stream state in formatting helpers. Because format flags, fill character, and precision are mutable stream state, any utility function that sets them without restoring them will corrupt the caller's formatting:
#include <iomanip>
#include <iostream>
void print_hex32(std::ostream& out, unsigned v) {
const auto flags = out.flags();
const char fill = out.fill();
const auto prec = out.precision();
out << "0x" << std::hex << std::uppercase
<< std::setfill('0') << std::setw(8) << v;
out.flags(flags);
out.fill(fill);
out.precision(prec);
}Prefer std::format (C++20) for new code. <iomanip> manipulators mutate hidden stream state and compose poorly; interleaved calls from different call sites corrupt each other silently. std::format from <format> is stateless, positional, type-safe, and roughly 2β3Γ faster to format:
#include <format> // C++20
#include <iostream>
// No state mutation, intent is local and explicit
std::cout << std::format("{:<14}{:>10.2f}\n", name, price);Use setiosflags/resetiosflags to set multiple flags atomically when you need to combine flags that std::hex etc. would set one at a time.
Common Pitfalls
setw is not sticky β the most common <iomanip> mistake. Applying setw once and then outputting multiple values gives the first value the desired width and all remaining values the default width of zero:
std::cout << std::setw(8); // applies only to the very next insertion
std::cout << a << b; // b gets width 0put_money and get_money silently produce wrong results in the "C" locale. The "C" locale defines no currency symbol or digit grouping. Imbue an explicit named locale before use, and handle the possibility that the locale name is not available on the target platform.
get_time does not zero-initialize std::tm. Fields not mentioned in the format string are left at whatever value the struct contained before the call. Always value-initialize with std::tm t{}; before passing it to get_time.
setbase silently falls back to base 10 for unsupported values. Arguments other than 8, 10, or 16 cause all basefield bits to be cleared, which the stream interprets as decimal. There is no error or diagnostic.
Stale precision after std::fixed. std::fixed changes what setprecision means: without it, precision counts significant figures; with it, precision counts decimal places. Switching between fixed and defaultfloat without re-issuing setprecision produces confusing output because the stored precision value carries over.
See Also
<ios>β non-parameterized format manipulators:std::fixed,std::hex,std::left,std::boolalpha, etc.<format>(C++20) βstd::formatandstd::print: stateless, type-safe replacement for most<iomanip>use cases<locale>βstd::money_put,std::money_get,std::time_put,std::time_getfacets underlying the C++11 manipulators<chrono>β C++20 adds directoperator<<forstd::chronoduration and time-point types, reducing the need forput_time