C++ alignment when printing cout <<
Solution 1
The ISO C++ standard way to do it is to #include <iomanip>
and use io manipulators like std::setw
. However, that said, those io manipulators are a real pain to use even for text, and are just about unusable for formatting numbers (I assume you want your dollar amounts to line up on the decimal, have the correct number of significant digits, etc.). Even for just plain text labels, the code will look something like this for the first part of your first line:
// using standard iomanip facilities
cout << setw(20) << "Artist"
<< setw(20) << "Title"
<< setw(8) << "Price";
// ... not going to try to write the numeric formatting...
If you are able to use the Boost libraries, run (don't walk) and use the Boost.Format library instead. It is fully compatible with the standard iostreams, and it gives you all the goodness for easy formatting with printf/Posix formatting string, but without losing any of the power and convenience of iostreams themselves. For example, the first parts of your first two lines would look something like:
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
Solution 2
Another way to make column aligned is as follows:
using namespace std;
cout.width(20); cout << left << "Artist";
cout.width(20); cout << left << "Title";
cout.width(10); cout << left << "Price";
...
cout.width(20); cout << left << artist;
cout.width(20); cout << left << title;
cout.width(10); cout << left << price;
We should estimate maximum length of values for each column. In this case, values of "Artist" column should not exceed 20 characters and so on.
Solution 3
See also: Which C I/O library should be used in C++ code?
struct Item
{
std::string artist;
std::string c;
integer price; // in cents (as floating point is not acurate)
std::string Genre;
integer disc;
integer sale;
integer tax;
};
std::cout << "Sales Report for September 15, 2010\n"
<< "Artist Title Price Genre Disc Sale Tax Cash\n";
FOREACH(Item loop,data)
{
fprintf(stdout,"%8s%8s%8.2f%7s%1s%8.2f%8.2f\n",
, loop.artist
, loop.title
, loop.price / 100.0
, loop.Genre
, loop.disc , "%"
, loop.sale / 100.0
, loop.tax / 100.0);
// or
std::cout << std::setw(8) << loop.artist
<< std::setw(8) << loop.title
<< std::setw(8) << fixed << setprecision(2) << loop.price / 100.0
<< std::setw(8) << loop.Genre
<< std::setw(7) << loop.disc << std::setw(1) << "%"
<< std::setw(8) << fixed << setprecision(2) << loop.sale / 100.0
<< std::setw(8) << fixed << setprecision(2) << loop.tax / 100.0
<< "\n";
// or
std::cout << boost::format("%8s%8s%8.2f%7s%1s%8.2f%8.2f\n")
% loop.artist
% loop.title
% loop.price / 100.0
% loop.Genre
% loop.disc % "%"
% loop.sale / 100.0
% loop.tax / 100.0;
}
Solution 4
IO manipulators are what you need. setw, in particular. Here's an example from the reference page:
// setw example
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw (10);
cout << 77 << endl;
return 0;
}
Justifying the field to the left and right is done with the left
and right
manipulators.
Also take a look at setfill. Here's a more complete tutorial on formatting C++ output with io manipulators.
Solution 5
The setw manipulator function will be of help here.
user69514
Updated on July 05, 2022Comments
-
user69514 almost 2 years
Is there a way to align text when printing using
std::cout
? I'm using tabs, but when the words are too big they won't be aligned anymore.Sales Report for September 15, 2010 Artist Title Price Genre Disc Sale Tax Cash Merle Blue 12.99 Country 4% 12.47 1.01 13.48 Richard Music 8.49 Classical 8% 7.81 0.66 8.47 Paula Shut 8.49 Classical 8% 7.81 0.72 8.49
-
Matthieu M. about 14 yearsYou should also mention the
left
andright
which allows to specify the alignment andsetfill
which allows to specify with which character completing (space by default). -
TOMKA about 14 years
Boost.Format
looks great. Straightforwardprintf
-style formatting with type-safety. -
Donal Fellows about 14 yearsPositional formats too, which is great since it means you can pull them from a localization file.