How do I correctly organize output into columns?
Asked Answered
R

5

30

The first thing that comes to my mind is to do a bunch of \t's, but that would cause words to be misaligned if any word is longer than any other word by a few characters.

For example, I would like to have something like:

Name    Last Name            Middle initial
Bob     Jones                M
Joe     ReallyLongLastName   T

Instead, by including only "\t"'s in my cout statement I can only manage to get

Name    Last Name            Middle initial
Bob     Jones                M
Joe     ReallyLongLastName                T

or

Name    Last Name            Middle initial
Bob     Jones    M
Joe     ReallyLongLastName   T

What else would I need to do?

EDIT: So I get that I should first count the maximum width of each column I want displayed, and then adding padding spaces accordingly. But how, and with what functions, can I go about doing this? Should I simply count the number of chars in a string and then go from there?

Romance answered 12/3, 2010 at 21:26 Comment(0)
P
39

Use std::setw from <iomanip>

e.g.

using std::cout;
using std::setw;

cout << setw(10) << "This" <<
        setw(10) << "is" <<
        setw(10) << "a" <<
        setw(10) << "test" << '\n';

Output:

      This        is         a      test
Priscilapriscilla answered 12/3, 2010 at 21:38 Comment(2)
I think you should also use cout << leftFoetation
Thanks to both you and Alexandre! I finally got what I wanted :)Romance
I
8

You should also take into account that different editors/viewers show text with different tab width. So using tabs, text which looks nicely arranged in one viewer may look ugly in another.

If you really want to produce nice arrangement, you could use padding spaces, and you could do two passes on your text: first count the maximum width of each column, then add the right amount of padding spaces to each column. For the latter, you could also use a tailor made printf call.

Update: Counting the column width basically means counting the length of strings you have in given column. It can be done using string::length() or strlen(), depending on whether you are using std::string or char* (the former is recommended). Then you just iterate through all the words in that column, compare the max word length you have so far, and if the current word is longer, you set that length to be the new max. If you store your words in an STL container, you can even use the std::max_element algorithm to do the job for you with a single function call.

Inoculum answered 12/3, 2010 at 21:29 Comment(2)
Thanks! How can I count the maximum width of each column?Romance
Thank you very much! That's an even more flexible implementation imo :PRomance
F
8

Use printf() padding with the minus flag for left-alignement

 printf("%-8s%-21s%-7s%-6s\n", "Name", "Last Name", "Middle", "initial");
 printf("%-8s%-21s%-7s%-6s\n", "Bob", "Jones", "M", "");
 printf("%-8s%-21s%-7s%-6s\n", "Joe", "ReallyLongLastName", "T", "");

Which produces:

Name    Last Name            Middle initial
Bob     Jones                M
Joe     ReallyLongLastName   T
Foetation answered 12/3, 2010 at 21:29 Comment(1)
Fair enough, but given the tags, perhaps an iostream solution would have been preferred.Mythopoeia
H
2

For situations like this typically two passes are required: one to discover the max width of each column and another to do the printing. For standard iostreams you can use the width() routine to have the iostream handle the padding for you automatically.

Hovey answered 12/3, 2010 at 21:30 Comment(0)
S
0

Use string formatting (from stdio) to display each line.

http://www.cppreference.com/wiki/c/io/printf

It'll let you set minimum field widths and so it will pad the rest of each field for you.

Silici answered 12/3, 2010 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.