我一直使用printf
,而我从未使用write
/ format
。有没有办法使用格式重现printf("%12.5e", $num)
?我在消化perlform documentation时遇到了麻烦,但我没有看到这样做的简单方法。
编辑:基于我得到的答案,我将继续使用printf。
答案 0 :(得分:2)
简短回答,不要使用格式。
未经检索的答案,当然,只需使用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格式版本)。
答案 1 :(得分:2)
我完全赞同Chas。欧文斯的格式一般。 Format
15年前非常光滑,但format
没有跟上Perl其他部分的进步。
这是我不时使用的面向行的输出技术。您可以使用formline,它是format
使用的公共内部函数之一。 Format
面向页面。执行诸如跨度列之类的操作或根据数据按行更改格式非常困难。您可以使用format
使用的相同文本格式逻辑格式化单行,然后自己输出该结果。
一个(凌乱)的例子:
use strict; use warnings;
sub print_line {
my $pic=shift;
my @args=@_;
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
语法相同。顶部的标签居中,“Rate - Operations / sec”标签跨越3列。
这显然不是“生产就绪”代码,但我认为你会有所偏差。您需要根据所需宽度等进一步检查列的总宽度。您必须手动执行格式化的一些工作,但您可以使用此方法获得更大的灵活性。例如,对于sprintf
的行的几个部分,使用此方法非常容易。
干杯。