Ch11.12.2: Complete <iomanip> Reference
The <iomanip> header provides manipulators that take arguments. These
manipulators modify the stream’s internal state, which persists until explicitly changed.
This is a fundamental design flaw — see “Why C++ iostream Is Fundamentally Flawed”
in Ch11.12. fast_io’s manipulators are stateless and do not suffer from these issues.
Field Width and Fill
| Manipulator | Description | Example |
|---|---|---|
std::setw(n) |
Set minimum field width to n characters |
std::cout << std::setw(10) << 42; |
std::setfill(c) |
Set fill character to c |
std::cout << std::setfill('0') << std::setw(5) << 42; |
Warning: std::setw only applies to the next output
operation, then resets to 0. This is inconsistent and error-prone.
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setw(10) << 42 << '\n'; // 42
std::cout << 42 << '\n'; // 42 (width reset!)
std::cout << std::setfill('0') << std::setw(5) << 42 << '\n'; // 00042
return 0;
}
Numeric Base
| Manipulator | Description | Example |
|---|---|---|
std::setbase(n) |
Set numeric base to n (8, 10, or 16) |
std::cout << std::setbase(16) << 255; (prints ff) |
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setbase(16) << 255 << '\n'; // ff
std::cout << std::setbase(8) << 255 << '\n'; // 377
std::cout << std::setbase(10) << 255 << '\n'; // 255
return 0;
}
Precision
| Manipulator | Description | Example |
|---|---|---|
std::setprecision(n) |
Set floating-point precision to n digits |
std::cout << std::setprecision(3) << 3.14159; (prints 3.14) |
Note: Precision persists until changed. Combined with
std::fixed or std::scientific, it controls decimal places.
#include <iostream>
#include <iomanip>
int main() {
double pi = 3.14159;
std::cout << std::setprecision(3) << pi << '\n'; // 3.14
std::cout << pi << '\n'; // 3.14 (precision persists!)
std::cout << std::fixed << std::setprecision(2) << pi << '\n'; // 3.14
std::cout << std::scientific << std::setprecision(4) << pi << '\n'; // 3.1416e+00
return 0;
}
Other Manipulators
| Manipulator | Description |
|---|---|
std::resetiosflags(f) |
Clear specified format flags |
std::setiosflags(f) |
Set specified format flags |
Format flags include: std::ios::left, std::ios::right,
std::ios::internal, std::ios::dec, std::ios::hex,
std::ios::oct, std::ios::fixed, std::ios::scientific,
std::ios::boolalpha, std::ios::showbase,
std::ios::showpoint, std::ios::showpos,
std::ios::skipws, std::ios::uppercase,
std::ios::unitbuf.
#include <iostream>
#include <iomanip>
int main() {
// Set flags
std::cout << std::setiosflags(std::ios::hex | std::ios::showbase);
std::cout << 255 << '\n'; // 0xff
// Reset flags
std::cout << std::resetiosflags(std::ios::hex);
std::cout << std::setiosflags(std::ios::dec);
std::cout << 255 << '\n'; // 255
return 0;
}
Why This Is Terrible
All of these manipulators modify the stream’s internal state. Consider:
#include <iostream>
#include <iomanip>
void print_hex(int value) {
std::cout << std::hex << value << '\n';
// Stream is now in hex mode!
}
int main() {
print_hex(255); // Prints "ff"
std::cout << 255 << '\n'; // Also prints "ff"!
// Must manually restore: std::cout << std::dec;
}
This is a maintenance nightmare. You must remember to restore the stream state after every use, or else later code will behave unexpectedly. Exceptions can leave the stream in an inconsistent state. Multiple threads can corrupt each other’s formatting.
fast_io’s manipulators are stateless:
#include <fast_io.h>
void print_hex(int value) {
using namespace ::fast_io::iomnp;
println(::fast_io::mnp::hex(value));
// No state to restore!
}
int main() {
using namespace ::fast_io::iomnp;
print_hex(255); // Prints "ff"
println(255); // Prints "255" (decimal, as expected)
}
Each manipulator applies only to the value it wraps. There is no global state to corrupt.