Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jan 22nd, 2008, 5:42 PM   #1
Sane
Banned
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 2,101
Rep Power: 6 Sane will become famous soon enough
Send a message via MSN to Sane
printf Alignment

A quick question. I know printf makes aligning variables easy. But what about absolute alignment? The only alignment I can figure out to do with printf is relative.

printf("This is a variable %3d. This is some text.\n", 5);
printf("This is a variable %3d. This is some text.\n", 15);

That is all fine and dandy. Unsurprisingly, it aligns the variables and outputs:

This is a variable   5. This is some text.
This is a variable  15. This is some text.

But that is relative to the text that comes before it. What if we want absolute alignment, where the interval specifies the character's position relative to the start of the line?

Garbage              5. This is some text.
...                 15. This is some text.

We can't use relative alignment, because then the 5 and 15 are no longer aligned with eachother, only with the text before it. Like so:

Garbage   5. This is some text.
...  15. This is some text.

So. We could potentially...
  • Use tabs ('\t'), but that only works if the text before each variable doesn't differ by the length of one tab.
  • Write a wrapper to printf, or use sprintf to add up each string with correct padding. But that kind of effort is a load of bullocks.
  • Perhaps rewind the cursor to the first'th position on the line, and then pad relative to that point, in effect producing an absolute pad. But is that even possible?

This is all so silly, for such a seemingly simple aesthetic.
Sane is offline   Reply With Quote
Old Jan 22nd, 2008, 6:21 PM   #2
Salem
Programmer
 
Join Date: Nov 2007
Posts: 33
Rep Power: 0 Salem is on a distinguished road
Re: printf Alignment

An indirect approach perhaps?
    printf( "%-10s %3d This is some text\n", "Garbage", 5 );
    printf( "%-10s %3d This is some text\n", "...", 15 );
produces
$ gcc foo.c
$ ./a.exe
Garbage      5 This is some text
...         15 This is some text
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Salem is offline   Reply With Quote
Old Jan 22nd, 2008, 7:02 PM   #3
Fall Back Son
Professional Programmer
 
Join Date: Oct 2006
Posts: 311
Rep Power: 3 Fall Back Son is on a distinguished road
Re: printf Alignment

You're simply saying that you want output where it outputs

blah blah blah 5. text text
blah blah blah blah 15. text text

So... in other words, you want the text to line up on each line in the same position regardless of the output before it, is that correct?
Fall Back Son is offline   Reply With Quote
Old Jan 22nd, 2008, 7:07 PM   #4
bldnfx
Newbie
 
Join Date: Dec 2007
Posts: 13
Rep Power: 0 bldnfx is on a distinguished road
Re: printf Alignment

Is there anything analogous to setw() available in C? I was able to make some nice columns regardless of the length of the members in the first position with:

C++ Syntax (Toggle Plain Text)
  1. // Some Loop prints out, say, 50 rows of:
  2.  
  3. cout << left << setw(20) << some_string
  4. << "Number of Occurrences: " << sameWrdCnt
  5. << endl;

And all columns come out nice nice.
Of course, this is directly from a C++ program, not C. some_string is a word that varies that varies in length in each row. (It could be different sized numbers.) The words are usually no more than a dozen characters, and then "Number of Occurrences: " and the word count all line up neatly at column twenty, regardless of first string length.

Last edited by bldnfx; Jan 22nd, 2008 at 7:25 PM.
bldnfx is offline   Reply With Quote
Old Jan 22nd, 2008, 8:36 PM   #5
Sane
Banned
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 2,101
Rep Power: 6 Sane will become famous soon enough
Send a message via MSN to Sane
Re: printf Alignment

Salem, that would work, but unfortunately the text that comes beforehand is the result of multiple printf statements. So it's basically garbage text that I can't control. Unless I were to wrap it all into one string with sprintf. But yuck.
Sane is offline   Reply With Quote
Old Jan 22nd, 2008, 10:32 PM   #6
Ancient Dragon
PFO God In Training
 
Ancient Dragon's Avatar
 
Join Date: Jun 2005
Location: near St Louis, MO. (USA)
Posts: 600
Rep Power: 4 Ancient Dragon is on a distinguished road
Re: printf Alignment

If Salem's suggestion won't work then I guess you could move the cursor to a specific location. How to do that is os-dependent. Here is another thread that discusses that a little bit.
Ancient Dragon is offline   Reply With Quote
Old Jan 22nd, 2008, 10:36 PM   #7
Ancient Dragon
PFO God In Training
 
Ancient Dragon's Avatar
 
Join Date: Jun 2005
Location: near St Louis, MO. (USA)
Posts: 600
Rep Power: 4 Ancient Dragon is on a distinguished road
Re: printf Alignment

Quote:
Originally Posted by bldnfx View Post
Is there anything analogous to setw() available in C? .
Yes, see Salem's example.
Ancient Dragon is offline   Reply With Quote
Old Jan 23rd, 2008, 5:16 AM   #8
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,260
Rep Power: 5 grumpy will become famous soon enough
Re: printf Alignment

Quote:
Originally Posted by Sane View Post
Salem, that would work, but unfortunately the text that comes beforehand is the result of multiple printf statements. So it's basically garbage text that I can't control. Unless I were to wrap it all into one string with sprintf. But yuck.
If you want to align something relative to the left hand column, you need to either control the preceding output (i.e. ensure that the preceding output finishes in the required position, which is what the C++ setw() approach does) or keep track of the length of what is output since the last newline.

Wrapping it into one string with sprintf() still requires you to keep track of the length of output since the last newline, but I suppose it's easier to count back if you do that.

Rewinding the cursor to the first position on a line can often be done practically for console output, by outputting a '\r' (a carriage return with no line feed). The problem with that is: any text you write to the same line will typically overwrite whatever is on the line. It also does not work for other types of output device (eg files) .... the data is still in the file. It also relies on things like console drivers, screen drivers, etc .... depending on what operating system your program runs on, and what hardware (eg display device) is attached to the machine.
grumpy is offline   Reply With Quote
Old Jan 23rd, 2008, 2:14 PM   #9
Salem
Programmer
 
Join Date: Nov 2007
Posts: 33
Rep Power: 0 Salem is on a distinguished road
Re: printf Alignment

Writing a wrapper for printf, using say vsnprintf() and some additional formatting of your own may seem a long way round, but it will give the most predictable results in the long run, and would be readily expandable to cater for future requirements.

Is glibc your standard C library by any chance?
You can register your own printf formats in this library, though I don't know if they get passed enough information to do what you want to do.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Salem is offline   Reply With Quote
Old Jan 25th, 2008, 1:36 AM   #10
WaltP
Programmer
 
Join Date: Oct 2007
Posts: 39
Rep Power: 0 WaltP is on a distinguished road
Re: printf Alignment

Quote:
Originally Posted by Sane View Post
Salem, that would work, but unfortunately the text that comes beforehand is the result of multiple printf statements. So it's basically garbage text that I can't control. Unless I were to wrap it all into one string with sprintf. But yuck.
Yuck indeed.

printf() returns the number of characters output. So use the return value to count the number of characters already displayed and use the '*' formatting character to align your numbers.

Another thing to know is how the %s modifier work. Run this to understand the details in how %n.ms formatting works:
#include <stdio.h>
#include <string.h>
#define NEXTCOL 38

int main()
{
    char *strs      = "ABCDEF";
    char *strl      = "ABCDEFGHIJKL";
    int   sizesingle= 9;
    int   size[][2]= {   3,  3,   -3,  3,    3,  9,   -3,  9,
                         3, -3,    3, -9,   -3, -3,   -3, -9,
                         3, 15,    3,-15,   -3, 15,   -3,-15,
                         0,  0,
                         9,  3,   -9,  3,   -9,  9,   -9, -3,
                        -9, -9,   -9, 15,   -9, -15,   9,  9,
                         9, -9,    9, -3,    9,  15,   9,-15,
                         0,  0,
                        15,  3,   15,  9,   15, -3,   15, -9,
                        15, 15,   15,-15,  -15,  3,  -15,  9,
                       -15, -9,  -15, 15,  -15,-15,  -15, -3,
                        -1,  0
                      };
    char buf[20];
                
    int  i = 0;
    int  j;
    
    j = printf("  Short -- %d chars <%s> ", strlen(strs), strs);
    while (j++ < NEXTCOL)  putchar(' ');
    printf("  Long -- %d chars <%s>  \n", strlen(strl), strl);
    printf("\n");
    
    j = sprintf(buf,"%*s", sizesingle, strs);
    j = printf("       %%%3ds (%2d)  <%s> ", sizesingle, j, buf);
    while (j++ < NEXTCOL)  putchar(' ');
    j = sprintf(buf,"%*s", sizesingle, strl);
    j = printf("       %%%3ds (%2d)  <%s> ", sizesingle, j, buf);
    printf("\n");
    
    j = sprintf(buf,"%*s", -sizesingle, strs);
    j = printf("       %%%3ds (%2d)  <%s> ", -sizesingle, j, buf);
    while (j++ < NEXTCOL)  putchar(' ');
    j = sprintf(buf,"%*s", -sizesingle, strl);
    j = printf("       %%%3ds (%2d)  <%s> ", -sizesingle, j, buf);
    printf("\n");
    
    j = sprintf(buf,"%.*s", sizesingle, strs);
    j = printf("       %%.%2ds (%2d)  <%s> ", sizesingle, j, buf);
    while (j++ < NEXTCOL)  putchar(' ');
    j = sprintf(buf,"%.*s", sizesingle, strl);
    j = printf("       %%.%2ds (%2d)  <%s> ", sizesingle, j, buf);
    printf("\n");
    
    j = sprintf(buf,"%.*s", -sizesingle, strs);
    j = printf("       %%.%2ds (%2d)  <%s> ", -sizesingle, j, buf);
    while (j++ < NEXTCOL)  putchar(' ');
    j = sprintf(buf,"%.*s", -sizesingle, strl);
    j = printf("       %%.%2ds (%2d)  <%s> ", -sizesingle, j, buf);
    printf("\n");
    
    printf("\n");

    while (size[i][0] != -1)
    {
    	if (size[i][0] != 0)
    	{ 
            j = sprintf(buf,"%*.*s", size[i][0], size[i][1], strs);
            j = printf("   %%%3d.%3ds (%2d)  <%s> ", size[i][0], size[i][1], j, buf);
            while (j++ < NEXTCOL)  putchar(' ');
            j = sprintf(buf,"%*.*s", size[i][0], size[i][1], strl);
            j = printf("   %%%3d.%3ds (%2d)  <%s> ", size[i][0], size[i][1], j, buf);
        }
        printf("\n");
        i++;
    }
    printf("done... \n");
    return 0;
}
__________________
Testing 001 010 011 100....
WaltP is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
printf or cout? d_heyzie C++ 15 Apr 18th, 2006 4:57 AM
Printing escape sequences using printf()? bivhitscar C 5 Nov 3rd, 2005 11:08 PM
printing "%" with printf ivan C 15 Oct 20th, 2005 8:22 AM
How to say the size of an array using printf ? colt C 2 May 19th, 2005 4:25 PM
printf() Planet_EN C++ 1 May 3rd, 2005 5:04 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 7:16 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC