Use streams and the standard stream formatting flags right
and left
that are part of ios_base
, defined in <ios>
. Example 4-29
shows how they work.
Example 4-29. Justify text
#include <iostream> #include <fstream> #include <string> #include <cstdlib> using namespace std; int main(int argc, char** argv) { if (argc < 3) return(EXIT_FAILURE); ifstream in(argv[1]); ofstream out(argv[2]); int w = 72; if (argc == 4) w = atoi(argv[3]); string tmp; out.setf(ios_base::right); // Tell the stream to // right-justify while (!in.eof()) { out.width(w); // Reset width after getline(in, tmp, '\n'); // each write out << tmp << '\n'; } out.close(); }
This example takes three arguments: an input file, an output file, and the width to right-justify to. You can use an input file like this:
With automatic download of Microsoft's (Nasdaq: MSFT) enormous SP2 security patch to the Windows XP operating system set to begin, the industry still waits to understand its ramifications. Home users that have their preferences set to receive operating-system updates as they are made available by Microsoft may be surprised to learn that some of the software they already run on their systems could be disabled by SP2 or may run very differently.
and make it look like this:
With automatic download of Microsoft's (Nasdaq: MSFT) enormous SP2 security patch to the Windows XP operating system set to begin, the industry still waits to understand its ramifications. Home users that have their preferences set to receive operating-system updates as they are made available by Microsoft may be surprised to learn that some of the software they already run on their systems could be disabled by SP2 or may run very differently.
The second text sample is right-justified to 50 characters.
The ios_base
class template has lots of flags for
formatting numeric and text data that is read from or written to streams. The two that
control how text is justified are right
and left
. They are static
const
members of ios_base
, and are of type fmtflags
(which
is implementation defined); all of this stuff is defined in <ios>
.
To set
formatting flags, use ios_base::setf
. This
ORs the flags you pass in with the existing flags on the stream. For example, this line
turns on right-justification:
out.setf(std::ios_base::right);
But right-justification doesn’t make much sense without a righthand margin to butt up
against. To set that margin, use ios_base::width
, like
this:
out.width(w);
This sets the width of the output field to the value passed in, meaning that when you
right-justify text, the beginning of the string will be padded with spaces as much as is
necessary to align the right end to the margin. Note that I set the width inside the loop
while I set the right
flag prior to the loop. I had to
do this because the width resets to zero after each write to the stream. Format flags are
not reset after writes, so I only had to initialize them once and be done with it.
It’s always good to be tidy and responsible, though, so there is one more thing you should do when using format flags: clean up after yourself.
Often, the stream you are writing to does not belong to you, especially if you are
writing a general-purpose library or API. For example, if you write a fancy logging
function that takes an output stream and a string
,
modifies the string
, sets the format flags, and writes
it to the stream, you have potentially unwanted side-effects. After client code calls your
logging function, its stream has potentially had its format flags rearranged. The solution
is to copy the old ones and restore them when you’re done.
For example, a responsible error logging function might look like this:
using namespace std;
void logError(ostream& out, const string& s) {
string tmp(s);
tmp.insert(0, "ERROR: ");
ios_base::fmtflags flgs = // setf returns the
out.setf(ios_base::left); // flags that were
// already there
out.width(72);
out << tmp << '\n';
out.flags(flgs);
// reset to original
}
The flags
member function works similarly to
setf
, but it doesn’t OR the flags you give it with
the stream’s current flags, it replaces them. Thus, when you call flags
and pass in the original formatting flags, you can
feel good that you cleaned up
after yourself.
Get C++ Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.