13

I would like to print columns using printf in C. I wrote this code:

#include <stdio.h> void printme(char *txt1, char *txt2, char *txt3) { printf("TXT1: %9s TXT2 %9s TXT3 %9s\n", txt1, txt2, txt3); } int main() { printme("a","bbbbbbbeeeeebbbbb","e"); printme("aaaaaaaa","bbbbbbbbbbbb","abcde"); return 0; } 

It works but I have such output:

TXT1: a TXT2 bbbbbbbeeeeebbbbb TXT3 e TXT1: aaaaaaaa TXT2 bbbbbbbbbbbb TXT3 abcde 

So the columns are not equal-width. Basicly, I would like to make it like this, that no matter how long is text in my argument, my function would ALWAYS print out a nice formatted columns. The question is: how can I do this?

By saing nice I meant that no matter how long text I pass to my printing function, it will always print out equal-width columns, for example:

I have this output that looks like this:

a cd` fg ij a cd fg ij a cd fg ij ab cd fg ij ab cd fg i j ab cd fg ij ab cd fg ij ab cde fgh ij ab cde fgh ij 

I want it to look like this (no matter how long my text arguments will be):

a cd` fg ij a cd fg ij a cd fg ij ab cd fg ij ab cd fg ij ab cd fg ij ab cd fg ij ab cde fgh ij ab cde fgh ij 
4
  • 2
    Define nice in nice formatted columns. Commented Jul 19, 2013 at 17:12
  • 2
    so scan your text in advance, figure out what the longest string is, and use that length for your column padding values. Commented Jul 19, 2013 at 17:14
  • Possibly a duplicate of stackoverflow.com/questions/2956296/… Commented Jul 19, 2013 at 17:21
  • Also a duplicate of stackoverflow.com/questions/1838388/… Commented Jul 19, 2013 at 17:21

4 Answers 4

13

If you want the strings to be truncated if they're larger than the column width, then you can just add a precision for the string format specification:

printf("TXT1: %9.9s TXT2 %9.9s TXT3 %9.9s\n", txt1, txt2, txt3); 

With that printf(), the output of your example program looks like:

TXT1: a TXT2 bbbbbbbee TXT3 e TXT1: aaaaaaaa TXT2 bbbbbbbbb TXT3 abcde 
Sign up to request clarification or add additional context in comments.

Comments

5

You can find the maximum length for txt1, txt2, and txt3, and then format it:

// compute the max string length of txt1 inputs in advance int s1 = strlen(firstTxt1); if (s1 < strlen(secondTxt1) s1 = strlen(secondTxt1); ... printf("%.*s %.*s %.*s\n", s1, txt1, s2, txt2, s3, txt3); 

2 Comments

What happens if you have continuous output (e.g. continuously printing information into a table-like structure) and suddenly the data for one column is longer than all its predecessors (the the column needs to be made wider)? I know of \b and \r but they don't really solve this problem.
Maybe it's my compiler, but why doesn't this method work for me? printf("%.*s",5,"hi"); just prints "hi" as if the length wasn't specified but %5s works fine. Do you have any links that explain specifically this in detail? I'm assuming the Google search term would be "formatting in printf"?
4

Take a look at my simple library, libtprint: https://github.com/wizzard/libtprint The code is pretty simple, you should be able to understand how it works.

Basically what you need is to play with the fields widths for each column and calculate alignment offsets.

Hope it helps !

Comments

3

Unfortunately, there is no TRIVIAL method for doing this.

You could do a two-pass method - in main():

char **data[] = { { "a","bbbbbbbeeeeebbbbb","e" }, {"aaaaaaaa","bbbbbbbbbbbb","abcde" } }; get_columwidths(data[0][0], data[0][1], data[0][2]); get_columwidths(data[1][0], data[1][1], data[1][2]); printme(data[0][0], data[0][1], data[0][2]); printme(data[1][0], data[1][1], data[1][2]); 

and then this:

int columnwidths[3]; void get_columwidths(const char *s1, const char *s2, const char *s3) { int len1 = strlen(s1); int len2 = strlen(s2); int len3 = strlen(s3); if (columnwidths[0] < len1) columnwidths[0] = len1; if (columnwidths[1] < len2) columnwidths[1] = len2; if (columnwidths[2] < len3) columnwidths[2] = len3; } void printme(char *txt1, char *txt2, char *txt3) { printf("TXT1: %*s TXT2 %*s TXT3 %*s\n", columnwidths[0], txt1, columnwidths[1], txt2, columnwidths[2], txt3); } 

1 Comment

+1 because using %*s instead of %.*s (note the period) like in the accepted answer this method does not print leading zeros when printing integers (%*d).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.