views:

168

answers:

2

How do you get "absolutely positioned" columns with cout, that leftaligns text and right-aligns numbers?

#include <iostream>
#include <iomanip>
using namespace std;

struct Human {
    char name[20];
    char name2[20];
    char name3[20];
    double pts;
};

int main() {
    int i;
    Human myHumen[3] = {
        {"Mr", "Alan", "Turing", 12.25},
        {"Ms", "Ada", "Lovelace", 15.25},
        {"Sir",  "Edgar Allan", "Poe", 45.25}
    };
    cout << "Name1" << setw(22) << "Name2" << setw(22) << "Name3" << setw(22) << "Rating" <<endl;
    cout << "-----------------------------------------------------------------------\n";
    for(i = 0; i < 3; i++) {
        cout << myHumen[i].name << setw(22) << myHumen[i].name2 << setw(22) << myHumen[i].name3 << setw(20) << myHumen[i].pts << endl;
    }//this didn't do nice printouts, with leftalign for text and rightalign with numbers
}
+5  A: 

You use the "left" and "right" manipulators:

cout << std::left  << std::setw(30) << "This is left aligned"
     << std::right << std::setw(30) << "This is right aligned";

An example with text + numbers:

typedef std::vector<std::pair<std::string, int> > Vec;
std::vector<std::pair<std::string, int> > data;
data.push_back(std::make_pair("Alan Turing", 125));
data.push_back(std::make_pair("Ada Lovelace", 2115));

for(Vec::iterator it = data.begin(), e = data.end(); it != e; ++it)
{
    cout << std::left << std::setw(20) << it->first
         << std::right << std::setw(20) << it->second << "\n";
}

Which prints:

Alan Turing                          125
Ada Lovelace                        2115
Manuel
I had fixed that myself concurrently with Roger. What change do you think I have undone?
Manuel
Also, I don't see any mentions to `std::right` in that alleged duplicate.
Manuel
@Manuel: Ah I must have seen in between edits.
dirkgently
@Manuel: The point is not about whether two questions are same to the letter -- but rather if they deal with the exact same solution. The mention of `right` doesn't make this any different, IMO. Of course, no need to get worked up.
dirkgently
@dirk - I think it's not a dup because here there is a explicit mention to "right-aligned numbers". But I admit the two questions are very close. I didn't mean to be harsh, sorry if you took it as such.
Manuel
A: 

This is going to be slightly unpopular, but you can just use printf for this kind of quick program. The formatting strings are easier to understand and use (given someone who groks both iostreams and printf).

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>

struct Human {
  char name[20];   // consider using std::string
  char name2[20];
  char name3[20];
  double pts;
};

int main() {
  using namespace std;
  Human people[3] = {
    {"Mr", "Alan", "Turing", 12.25},
    {"Ms", "Ada", "Lovelace", 15.25},
    {"Sir",  "Edgar Allan", "Poe", 45.25}
  };
  printf("%-22s%-22s%-22s%20s\n", "Name1", "Name2", "Name3", "Rating");
  cout << string(22 * 3 + 20, '-') << '\n';
  for (int i = 0; i < 3; i++) {
    Human const& h = people[i];
    printf("%-22s%-22s%-22s%20f\n", h.name, h.name2, h.name3, h.pts);
  }
  return 0;
}

It is safe (by default, see std::sync_with_stdio) to mix cout and printf, and a good compiler can check the types of the format strings for you, too (-Wall in gcc).

Roger Pate
It is never a good idea to mix C and C++ style i/o (any i/o before `sync_with_stdio` has implementation-defined semantics upto the point of call). If you take out the stray `cout`-- this is definitely an alternative ;-) Note, you can declare the `int i` in the `for` loop. Also, a mention about `#include <cstdio>` would make this sweet. My $0.02.
dirkgently
@dirk: I left the cout in to show that you can mix them. The whole point of sync_with_stdio existing is that it's safe unless you explicitly request otherwise (and thus possibly get a small performance boost), and it is *not* implementation-defined if you don't call it. (What is implementation-defined is calling it *after* output.)
Roger Pate
I also left out the whole first part of his program, which makes this give errors if you try to compile it, but you're right it's not that much work to make this work.
Roger Pate