I/O Manipulators
reading
See the cppreference.com page on iomanip
We’ve been using the stream operators for I/O and have occasionally changed the formatting. Let’s look at this in more detail now.
There are a few ways to specify the format of numbers:
std::fixed
: output all floating point numbers in fixed form, e.g.0.00001
std::scientific
: output all floating point numbers in scientific notation, e.g.,1.e-5
std::defaultfloat
: use the default formatting.
We can control the precision of the output with
std::setprecision(N)
: outputsN
decimal places
To output in columns, we can use:
std::setw(N)
: use a column with aN
charactersset::setfill(c)
: fill empty places in a column with thechar c
.std::left
: flush left in the columnstd::right
: flush right in the column
Note
Most of these are persistent—once you set them, the format will remain in place until
it is reset. The one exception is std::setw()
—this needs to be set before each
output.
Here’s an example using these different formats:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <string>
#include <cassert>
int main() {
std::vector<double> numbers{M_PI, 0.001, 9.569299999e-6, 1234.5678, 1.25689354e10, 6.74e5};
std::vector<std::string> words{"may", "the", "force", "be", "with", "you"};
// save the current I/O flags
std::ios cout_state(nullptr);
cout_state.copyfmt(std::cout);
// default I/O
std::cout << "default I/O" << std::endl;
for (auto &e : numbers) {
std::cout << e << " ";
}
std::cout << std::endl << std::endl;
// scientific
std::cout << "scientific" << std::endl;
std::cout << std::scientific;
for (auto &e : numbers) {
std::cout << e << " ";
}
std::cout << std::endl << std::endl;
// fixed
std::cout << "fixed" << std::endl;
std::cout << std::fixed;
for (auto &e : numbers) {
std::cout << e << " ";
}
std::cout << std::endl << std::endl;
// defaultfloat
std::cout << "defaultfloat" << std::endl;
std::cout << std::defaultfloat;
for (auto &e : numbers) {
std::cout << e << " ";
}
std::cout << std::endl << std::endl;
// now set precision -- note: this is sticky
std::cout << "setprecision" << std::endl;
std::cout << std::setprecision(3);
for (auto &e : numbers) {
std::cout << e << " ";
}
std::cout << std::endl << std::endl;
// setfill and setw
std::cout << "setfill / setw" << std::endl;
std::cout << std::setfill('*');
for (auto &e : numbers) {
std::cout << std::setw(10) << e << " ";
}
std::cout << std::endl << std::endl;
// reset
std::cout << "reset" << std::endl;
std::cout.copyfmt(cout_state);
for (auto &e : numbers) {
std::cout << e << " ";
}
std::cout << std::endl << std::endl;
// now let's output stuff in columns -- we are assuming that words and numbers are the same length
assert(words.size() == numbers.size());
for (int i = 0; i < words.size(); ++i) {
std::cout << std::setw(10) << words[i] << " " << std::setw(15) << numbers[i] << std::endl;
}
std::cout << "left" << std::endl;
assert(words.size() == numbers.size());
for (int i = 0; i < words.size(); ++i) {
std::cout << std::setw(10) << std::left << words[i] << " " << std::setw(15) << std::right << numbers[i] << std::endl;
}
}