2012-10-23 38 views
2

我试图将输出格式化为看起来像列中的格式。我正在尝试使用printf函数。使用Perl中的'printf'格式化输出

这是我有:

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

for ($he = 0; $he <= 6; $he++) { 
    if (@quantity[$he] != 0) { 
     printf("%d %10s %12.2f %10.2f\n", @quantity[$he], @selections[$he], @prices[$he], @prices[$he] * @quantity[$he]) 
    } 
} 

我试图让这个在for循环排队的“数量”的if声明内的第二个printf,“说明”, “Unit \ $”和“Total”。

+0

这是什么问题? –

+0

输出结果不一致。 –

+2

使用'使用警告'找到4个错误! – ikegami

回答

1

您需要在两种格式使用相同的数字:

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

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

注意,12.2单元(12位+ 1点+ 2个位数),这就是为什么我以第一种格式写下15。这同样适用于13.


另请注意,您正在访问错误的数组元素。

而不是@quantity[$he]使用$quantity[$he]。也就是说,将@替换为$

+2

'@quantity [$ he]'应该写成'$ quantity [$ he ]'。 – TLP

+0

这也不起作用。当我执行此操作时,$ quantity [$ he]和$ selections [$ he]之间只有一个空格,但我希望两列匹配: –

+0

我认为它可能与@selections中的字符串有关是不同的长度,任何方式? –

1

很久以前,Perl主要用于格式化文件。它仍然具有这些功能,尽管自从Perl 4.x发布以来,我还没有看到它在程序中使用。

查看perlform文档,format函数和write函数。

我想给你一个例子,看看代码会是什么样子,除非我多年没有这样做。否则,请使用printf声明。您可以用%-10.10s格式类型来限制文本字段的大小。这表示左对齐字符串,并将其填充到10个字符,但不超过10个字符。

我也建议你拿到一本关于现代 Perl。一个会教你关于references

我已经重写了您的程序以使用引用。请注意,所有数据现在都在一个数组中,而不是分散在四个单独的数组上,您希望将索引保留在一起。

我可以通过说$item[1]->{ENTREE}来谈论ENTREE$item[1]。阅读起来更容易,维护也更容易。

另请注意,我已更改您的for循环。在你的,你必须知道你有七件物品。如果你添加了一个新的项目,你将不得不改变你的循环。在我的,我使用$#menu获得我的菜单的最后一个索引。然后我使用(0..$#menu)自动从0循环到@menu阵列中的最后一项。

而且,当你在它:

  • 通知的printf报表格式。
  • 请注意使用use strict;use warnings;。这将会遇到很多错误。
  • 请注意我使用圆括号和大括号来标记代码块的首选方式。这是首选的方法。

而且,现在的程序:

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

为什么你不只是做一个'foreach我的$ item(@menu)'? –

+0

我发布了我的答案几个小时后我想到了同样的事情。最初的'for'循环是OP使用索引的,这样做更好,每个'$ item'都是一个散列的引用。 –