2010-09-14 78 views

回答

2

简短的回答,不要使用格式。

Unresearched答案,肯定的是,只要使用sprintf

#!/usr/bin/perl 

use strict; 
use warnings; 

our $num = .005; 

write; 

format STDOUT = 
@>>>>>>>>>>>>>>>>> 
sprintf("%12.5e", $num) 
. 

严重的是,如果你需要的东西如Perl 5种格式,看看Perl6::Form(注意,这是一个Perl 5模块,它只是实现了提出了Perl 6版本的格式)。

+0

+1:这是真正的时间让遗留'格式'去...... – dawg 2010-09-14 20:47:41

2

我完全同意Chas。欧文斯的格式一般。 Format 15年前真的很光滑,但format还没有跟上其余Perl的进步。

这是一种面向行输出的技术,我使用时间。您可以使用formline,这是format使用的公共内部函数之一。 Format是面向页面的。根据数据很难做到像跨列这样的事情或按行改变格式。您可以使用format使用的相同文本格式逻辑格式化一行,然后自行输出结果。

A(杂乱)例如:

use strict; use warnings; 

sub print_line { 
    my $pic=shift; 
    my @[email protected]_; 

    formline($pic,@args); 
    print "$^A\n"; 
    $^A=''; 
} 

my ($wlabel, $wlow, $whigh, $wavg)=(0,0,0,0); 
my ($plabel,$plow,$phigh, $pavg); 
my ($s_low,$s_high,$s_avg)=qw(%.2f %.2e %.2f); 


my @results=(["Label 1", 3.445, 0.00006678, .025], 
      ["Label 2", 12.5555556, 55.112, 1.11], 
      ["Wide Label 3", 1231.11, 1555.0, 66.66]); 

foreach (@results) { 
    my $tmp; 
    $tmp=length($_->[0]); 
    $wlabel=$tmp if $tmp>$wlabel; 

    $tmp=length(sprintf($s_low,$_->[3])); 
    $wlow=$tmp if $tmp>$wlow; 

    $tmp=length(sprintf($s_high,$_->[2])); 
    $whigh=$tmp if $tmp>$whigh; 

    $tmp=length(sprintf($s_avg,$_->[1])); 
    $wavg=$tmp if $tmp>$wavg; 
} 

print "\n\n"; 
my @a1=("Label", "Rate - Operations/sec"); 
my @a2=("Text", "Average", "High", "Low"); 
my @a3=("----------", "-------", "----", "---"); 
my $l1fmt="@".'|' x $wlabel." @".'|'x($whigh+$wavg+$wlow+6); 

my $l2fmt="@".'|' x $wlabel." @".'|' x $wavg." @".'|' x $whigh . 
      " @".'|' x $wlow; 
print_line($l1fmt,@a1); 
print_line($l2fmt,@a2); 
print_line($l2fmt,@a3); 

$plabel="@".'>' x $wlabel; 
$phigh="@".'>' x $whigh; 
$pavg="@".'>' x $wavg; 
$plow="@".'<' x $wlow; 


foreach (@results) { 
    my $pic="$plabel $pavg $phigh $plow"; 
    my $mark=$_->[0]; 
    my $avg=sprintf($s_avg,$_->[1]); 
    my $high=sprintf($s_high,$_->[2]); 
    my $low=sprintf($s_low,$_->[3]); 
    print_line($pic,$mark,$avg,$high,$low); 
} 
print "\n\n"; 

输出此:

Label   Rate - Operations/sec 
    Text   Average  High  Low 
----------  -------  ----  --- 
     Label 1  3.44 6.68e-05 0.03 
     Label 2  12.56 5.51e+01 1.11 
Wide Label 3 1231.11 1.56e+03 66.66 

注意,列的宽度是基于所述数据的宽度设定由sprintf格式字符串作为格式化。然后,您可以左转,居中,右对齐该结果。 “低”数据列左对齐,其余数据右对齐。您可以通过标量$plow中使用的符号更改此值,它与format语法相同。顶部的标签居中,“速率 - 操作/秒”标签跨越3列。

这显然不是“生产就绪”的代码,但你会得到漂移。您需要根据所需的宽度进一步检查列的总宽度等。您必须手动执行格式为您所做的一些工作,但使用此方法的灵活性要高得多。例如,对于sprintf行的几个部分,使用此方法非常简单。

干杯。

+1

即使15年前,我从来没有使用格式。我认为即使在使用Perl 4时,它们也是一种遗产! – Gabe 2010-09-15 04:25:53

+0

@downvoter:为什么? – dawg 2010-09-19 03:37:02

相关问题