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
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 $
.
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:
printf
statement formats.use strict;
and use warnings;
. That will catch a lot of errors.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