perlnovice1900 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Wise Monks, I am having trouble getting four variables to printf their numeric counts to the screen - all right aligned. Right now they are all left aligned (I have tried with and without -s). Here is my code:
printf ( "%-16s $FreqP \n" , "Freq(Z+):") ; printf ( "%-16s $FreqN \n" , "Freq(Z-):") ; printf ( "%-16s $FreqZ \n" , "Freq(0):") ; printf ( "%-16s $Sum \n" , "Total:") ;
I have also tried this way:
#printf ( "Freq(Z+): %16d\n" , $FreqP) ; #printf ( "Freq(Z-): %16d\n" , $FreqN) ; #printf ( "Freq(0): %16d\n" , $FreqZ) ; #printf ( "Total: %19d\n" , $Sum) ;
Thank you for ANY input! -Steven

Replies are listed 'Best First'.
Re: How to right align outputs of stored data in a variable?
by davido (Cardinal) on Feb 04, 2017 at 20:09 UTC

    Your second approach would work if you were aligning your template string correctly, and if it were not commented out. I'm assuming you want space-padding:

    use List::Util qw(sum); my ($FreqP, $FreqN, $FreqZ) = map {int rand 41600} 0..2; my $Sum = sum($FreqP, $FreqN, $FreqZ); printf ( "Freq(Z+): %16d\n" , $FreqP) ; printf ( "Freq(Z-): %16d\n" , $FreqN) ; printf ( "Freq(0): %16d\n" , $FreqZ) ; printf ( "Total: %19d\n" , $Sum) ;

    The output:

    Freq(Z+): 32571 Freq(Z-): 25729 Freq(0): 9025 Total: 67325

    If you wanted zero padding, just apply the appropriate modification to the printf templates (Insert a 0 character at the start of the field widths):

    printf ( "Freq(Z+): %016d\n" , $FreqP) ;

    The documentation for printf templates is in sprintf.


    Dave

      Thank you Dave!

      I did want the padding to make things a little more spaced out, also apologies for keeping the comments in on my second approach.

      I appreciate your help.

      -Steven

        A slight variation that would entail less space-futzing between the columns would be something like:

        c:\@Work\Perl\monks>perl -wMstrict -le "use List::Util qw(sum); ;; my $Sum = sum my ($FreqP, $FreqN, $FreqZ) = map { int rand 41600 } 0. +.2; ;; my $fmt = qq{%-9s%16d \n}; printf $fmt, 'Freq(Z+):', $FreqP; printf $fmt, 'Freq(Z-):', $FreqN; printf $fmt, 'Freq(0):', $FreqZ; printf $fmt, 'Total:', $Sum; " Freq(Z+): 3107 Freq(Z-): 27423 Freq(0): 3837 Total: 34367


        Give a man a fish:  <%-{-{-{-<

Re: How to right align outputs of stored data in a variable?
by Marshall (Canon) on Feb 05, 2017 at 20:16 UTC
    I like the answer from davido. Some additional comments for you...

    The printf() "format spec" reserves a minimum field width. In some cases that minimum width will be exceeded to print what is necessary.

    When there are multiple variables, I always put an explicit space in the format spec to guarantee that the printout will have a space between columns. If you have a 5 digit integer, do not use %6d and count on that leading column to be blank. Use " %5d". If 8 digits show up for the integer, they will get printed and perhaps more importantly a space will separate that column from the previous one. Here are some examples:

    #!/usr/bin/perl use strict; use warnings; my $x = "a_long_string"; print "*using a single field:\n"; printf "%3s\n","a"; printf "%3s\n","abc"; printf "%3s\n",$x; print "\n*using format with 2 fields:\n"; printf "%3s%4s\n", "abc", "a"; printf "%3s%4s\n", "abc", "abcd"; printf "%3s%4s\n", $x, "abcd"; printf "%3d%3d\n", 123, 456; # # better, use a explict space between format fields # print "\n*using explict space between 2 fields\n"; printf "%3s %4s\n", $x, "abcd"; printf "%3d %3d\n", 123789, 456; __END__ *using a single field: a abc a_long_string *using format with 2 fields: abc a abcabcd a_long_stringabcd 123456 *using explict space between 2 fields a_long_string abcd 123789 456
      ... a minimum field width. ... that ... will be exceeded to print what is necessary. ... an explicit space in the format spec to guarantee that the printout will have a space between columns.

      A good point. I guess I was distracted by the fact that the field labels already had semicolons to delimit the name fields. :)


      Give a man a fish:  <%-{-{-{-<

        No problem. Your post++ also illustrated a good point that might be missed by many... The "format string" can be calculated dynamically. This is also possible in C using sprintf(). But here is a Perl demo:
        #!/usr/bin/perl use strict; use warnings; my $textlength=3; my $numlength=1; # on purpose too narrow my $fmt = "%-$textlength".'s '."%$numlength"."d\n"; print "format is:$fmt"; printf $fmt, "a",1; printf $fmt, "abc",123; printf $fmt, "abcdef",12345; __END__ prints: format is:%-3s %1d a 1 abc 123 abcdef 12345
        I like uniformity in the code and probably would have written the OP's code something like this:
        #!/usr/bin/perl use strict; use warnings; use List::Util qw(sum); my ($FreqP, $FreqN, $FreqZ) = map {int rand 41600} 0..2; my $Sum = sum($FreqP, $FreqN, $FreqZ); printf ( "Freq(Z+): %19d\n" , $FreqP) ; printf ( "Freq(Z-): %19d\n" , $FreqN) ; printf ( "Freq(0): %19d\n" , $FreqZ) ; printf ( "Total: %19d\n" , $Sum) ; __END__ Freq(Z+): 11640 Freq(Z-): 3527 Freq(0): 33243 Total: 48410
Re: How to right align outputs of stored data in a variable?
by vkhera (Novice) on Feb 08, 2017 at 13:16 UTC
    Have a look at the Text::Table module as well. I use it frequently to let it sort out all the formatting of my tabular data.