Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
There are six standard manipulators, such as setw( ),
that take arguments. These are defined in the header file <iomanip>, and are summarized in the following table:
Manipulator
|
effect
|
setiosflags(fmtflags n)
|
Equivalent to a call to setf(n). The setting remains in
effect until the next change, such as ios::setf( ).
|
resetiosflags(fmtflags n)
|
Clears only the format flags specified by n. The
setting remains in effect until the next change, such as ios::unsetf( ).
|
setbase(base n)
|
Changes base to n, where n is 10, 8, or 16.
(Anything else results in 0.) If n is zero, output is base 10, but
input uses the C conventions: 10 is 10, 010 is 8, and 0xf is 15. You might as
well use dec, oct, and hex for output.
|
setfill(char n)
|
Changes the fill character to n, such as ios::fill( ).
|
setprecision(int n)
|
Changes the precision to n, such as ios::precision( ).
|
setw(int n)
|
Changes the field width to n, such as ios::width( ).
|
If you re doing a lot of
formatting, you can see how using manipulators instead of calling stream member
functions can clean up your code. As an example, here s the program from the
previous section rewritten to use the manipulators. (The D( ) macro
is removed to make it easier to read.)
//: C04:Manips.cpp
// Format.cpp using manipulators.
#include <fstream>
#include <iomanip>
#include <iostream>
using namespace std;
int main() {
ofstream trc("trace.out");
int i = 47;
float f = 2300114.414159;
char* s = "Is there any more?";
trc << setiosflags(ios::unitbuf
| ios::showbase | ios::uppercase
| ios::showpos);
trc << i << endl;
trc << hex << i <<
endl
<< oct << i <<
endl;
trc.setf(ios::left, ios::adjustfield);
trc << resetiosflags(ios::showbase)
<< dec << setfill('0');
trc << "fill char: " <<
trc.fill() << endl;
trc << setw(10) << i << endl;
trc.setf(ios::right, ios::adjustfield);
trc << setw(10) << i << endl;
trc.setf(ios::internal, ios::adjustfield);
trc << setw(10) << i << endl;
trc << i << endl; // Without setw(10)
trc << resetiosflags(ios::showpos)
<< setiosflags(ios::showpoint)
<< "prec = " <<
trc.precision() << endl;
trc.setf(ios::scientific, ios::floatfield);
trc << f << resetiosflags(ios::uppercase)
<< endl;
trc.setf(ios::fixed, ios::floatfield);
trc << f << endl;
trc << f << endl;
trc << setprecision(20);
trc << "prec = " <<
trc.precision() << endl;
trc << f << endl;
trc.setf(ios::scientific, ios::floatfield);
trc << f << endl;
trc.setf(ios::fixed, ios::floatfield);
trc << f << endl;
trc << f << endl;
trc << setw(10) << s << endl;
trc << setw(40) << s << endl;
trc.setf(ios::left, ios::adjustfield);
trc << setw(40) << s << endl;
} ///:~
You can see that a lot of the multiple statements have been
condensed into a single chained insertion. Notice the call to setiosflags( )
in which the bitwise-OR of the flags is passed. This could also have been done
with setf( ) and unsetf( ) as in the previous example.
When using setw( ) with an output stream, the
output expression is formatted into a temporary string that is padded with the
current fill character if needed, as determined by comparing the length of the
formatted result to the argument of setw( ). In other words, setw( )
affects the result string of a formatted output operation. Likewise,
using setw( ) with input streams only is meaningful when reading strings,
as the following example makes clear:
//: C04:InputWidth.cpp
// Shows limitations of setw with input.
#include <cassert>
#include <cmath>
#include <iomanip>
#include <limits>
#include <sstream>
#include <string>
using namespace std;
int main() {
istringstream is("one 2.34 five");
string temp;
is >> setw(2) >> temp;
assert(temp == "on");
is >> setw(2) >> temp;
assert(temp == "e");
double x;
is >> setw(2) >> x;
double relerr = fabs(x - 2.34) / x;
assert(relerr <=
numeric_limits<double>::epsilon());
} ///:~
If you attempt to read a string, setw( )
will control the number of characters extracted quite nicely up to a point.
The first extraction gets two characters, but the second only gets one, even
though we asked for two. That is because operator>>( ) uses
white space as a delimiter (unless you turn off the skipws flag). When
trying to read a number, however, such as x, you cannot use setw( )
to limit the characters read. With input streams, use only setw( )
for extracting strings.
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |