2010-04-15 31 views
4

我試圖輸出文件看起來像這樣(更多在http://pastebin.com/dpBAY8Sb):當值可能是數字或字符串時,如何將列與Perl的printf對齊?

 10.1.1.1  100 <unknown>    <unknown>    <unknown>   <unknown>   <unknown> 
72.12.148.186  94 Canada     Hamilton    ON    43.250000  -79.833300 0.00 
72.68.209.149  24 United States   Richmond Hill   NY    40.700500  -73.834500 611.32 
72.192.33.34   4 United States   Rocky Hill    CT    41.657800  -72.662700 657.48 

我找不到如何輸出我必須有一個浮動Poing的和格式化列之間的距離進行格式化。我目前的代碼看起來像這樣。

if (defined $longitude){ 
    printf FILE ("%-8s %.6f","",$longitude); 
}else{ 
$longitude = "<unknown>"; 
    printf FILE ("%-20s ",$longitude); 
} 

額外""拋出了整列,它看起來像這樣(更多在http://pastebin.com/kcwHyNwb)。

10.1.1.1    100  <unknown>   <unknown>   <unknown>   <unknown>   <unknown>     
72.12.148.186  94  Canada    Hamilton    ON      43.250000   -79.833300   0.00 
72.68.209.149  24  United States  Richmond Hill  NY      40.700500   -73.834500   571.06 

回答

1

我認爲你的未知格式字符串有點偏離。

這裏是我的示例:

foreach $longitude (1,2.12345678,undef) { 
    if (defined $longitude){ 
    printf ("|%-8s %.6f|\n","",$longitude); 
    }else{ 
    $longitude2 = "<unknown>"; 
    printf ("| %16s|\n",$longitude2); 
    } 
} 

和輸出(帶有" %16s"未知格式我加豎條看到對齊清楚):

|   1.000000| 
|   2.123457| 
|  <unknown>| 

附:看看您的示例對齊方式與您生成的實際代碼的對比情況,看起來狀態<unknown>也可能是錯誤對齊的。要驗證,請使用上面所做的相同技巧,將每個字段的格式字符串包含在|中,以查看一個字段結束,另一個字段開始的位置。

2

這些問題的訣竅是儘可能減少分支和重複代碼。內置的printf並不是那麼特別。它需要一個格式參數和一個列表,所以你只需要給它正確的東西,然後調用它一次。另外,還可以通過使用類似Scalar::Utillooks_like_number,以確保你希望你的數據更接近與您的檢查更精確:

use Scalar::Util qw(looks_like_number); 

while(<DATA>) 
    { 
    chomp(my $longitude = $_); 

    my($format, @arguments) = do { 
     looks_like_number $longitude ? 
      ("|%-8s %.6f|\n", '', $longitude) 
       : 
      ("| %16s|\n",  '<unknown>') 
     }; 

    printf $format, @arguments; 
    } 

__END__ 
1 
2.12345678 
undef 
0 

fred 

現在你有一個printf,你不需要額外的$longitude2變量。您可以使用printf來玩一些額外的技巧,因此您可以自動調整列的大小,但我們現在不會擔心。 :)

0

我個人通過他們throught同一printf的

# You can choose prefered way of laying out the logic ! 
    $text = sprintf ("%.6f",$longitude); 
# or 
    $text = '<unknown>' ; 

然後

printf ("| %16s|\n",$text); 

然後,如果16變爲20兩個位在步驟適應。

相關問題