Formatting output with 'printf' in Perl

后端 未结 2 1627
南笙
南笙 2021-01-23 03:14

I\'m trying to format my output to look like it\'s in columns. I\'m trying to use the printf function.

Here\'s what I have:

printf(\"%s %10s %12s %10s\\n         


        
相关标签:
2条回答
  • 2021-01-23 04:11

    You need to use the same numbers in the two formats:

    printf("%3s %10s %15s %13s\n", "Qty", "Desc.", "Unit \$", "Total");
    

    and

    printf("%3d %10s %12.2f %10.2f\n", @quantity[$he], @selections[$he], @prices[$he], @prices[$he]*@quantity[$he])
    

    Note that 12.2 means (12 digits + 1 point + 2 digits), which is why I wrote 15 in the first format. The same goes for the 13.


    Also note that you're accessing array elements incorrectly.

    Instead of @quantity[$he] use $quantity[$he]. That is, replace the @ with a $.

    0 讨论(0)
  • 2021-01-23 04:14

    Long time ago, Perl was mainly used for formatting files. It still has these capabilities although I haven't seen it used in a program since Perl 4.x came out.

    Check out the perlform documentation, the format function, and the write function.

    I'd give you an example on what the code would look like except I haven't done it in years. Otherwise, use the printf statement. You can limit the size of a text field with a %-10.10s type of format. This says to left justify the string, and pad it out to 10 characters, but not more than 10 characters.

    I also suggest you get a book on modern Perl. One that will teach you about references.

    I've rewritten your program to use references. Notice that all of the data is now in a single array instead of spread over four separate arrays that you hope you keep the index together.

    I can talk about the ENTREE of $item[1] by saying $item[1]->{ENTREE}. It's easier to read and easier to maintain.

    Also note that I've changed your for loop. In yours, you had to know that you had seven items. If you added a new item, you'd have to change your loop. In mine, I use $#menu to get the last index of my menu. I then use (0..$#menu) to automatically loop from 0 to the last item in the @menu array.

    And, while you're at it:

    • Notice the printf statement formats.
    • Notice the use of use strict; and use warnings;. That will catch a lot of errors.
    • Notice the preferred way I use parentheses and curly braces to mark off blocks of code. This is the preferred method.

    And, now the program:

    use strict;
    use warnings;
    
    my @menu = (
        { ENTREE => "Hamburger",    PRICE => 3.49, QUANTITY => 3 },
        { ENTREE => "Frankfurter",  PRICE => 2.19, QUANTITY => 0 },
        { ENTREE => "French Fries", PRICE => 1.69, QUANTITY => 0 },
        { ENTREE => "Large Coke",   PRICE => 1.79, QUANTITY => 4 },
        { ENTREE => "Medium Coke",  PRICE => 1.59, QUANTITY => 0 },
        { ENTREE => "Small Coke",   PRICE => 1.39, QUANTITY => 0 },
        { ENTREE => "Onion Rings",  PRICE => 1.19, QUANTITY => 8 },
    );
    
    printf "%-3.3s %-10.10s %-6.6s %s\n\n", 'Qty', 'Desc.', 'Unit $', 'Total';
    
    # Use $#menu to get the number of items in the array instead of knowing it's 6
    
    foreach my $item (0..$#menu) {
    
        # Dereference $menu[$item] to make $menu_item a hash
        # This makes the syntax easier to read.
        my %menu_item = %{ $menu[$item] };
    
        if ( $menu_item{QUANTITY} ) {
            printf "%3d %-10.10s %9.2f %7.2f\n",
            $menu_item{QUANTITY}, $menu_item{ENTREE}, $menu_item{PRICE},
            $menu_item{QUANTITY} * $menu_item{PRICE};
        }
    }
    

    OUTPUT:

    Qty Desc.      Unit $ Total
    
      3 Hamburger  3.49   10.47
      4 Large Coke 1.79    7.16
      8 Onion Ring 1.19    9.52
    
    0 讨论(0)
提交回复
热议问题