2012-10-23 36 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'都是一個散列的引用。 –