perl中的固定字段宽度数字输出

perl中的固定字段宽度数字输出,perl,format,Perl,Format,我有一个介于0.001和1000之间的随机数,需要perl以5个字符的固定列宽打印它。也就是说,如果它太长,它应该是圆形的,如果它太短,它应该用空格填充 我在网上找到的所有东西都建议使用sprintf,但如果数字太长,sprintf会忽略字段宽度 有没有办法让perl来做这件事 什么不起作用: my $number = 0.001 + rand(1000); my $formattednumber = sprintf("%5f", $number); print <<EOF;

我有一个介于0.001和1000之间的随机数,需要perl以5个字符的固定列宽打印它。也就是说,如果它太长,它应该是圆形的,如果它太短,它应该用空格填充

我在网上找到的所有东西都建议使用sprintf,但如果数字太长,sprintf会忽略字段宽度

有没有办法让perl来做这件事

什么不起作用:

my $number = 0.001 + rand(1000);
my $formattednumber = sprintf("%5f", $number); 
print <<EOF;
   $formattednumber

EOF
my$number=0.001+兰特(1000);
我的$formattednumber=sprintf(“%5f”,$number);

打印您需要动态定义
sprintf
模式。小数位数取决于小数点左侧的位数

此函数将为您执行此操作

use strict;
use warnings 'all';
use feature 'say';

sub round_to_col {
    my ( $number, $width ) = @_;

    my $width_int = length int $number;
    return sprintf(
        sprintf( '%%%d.%df', $width_int, $width - 1 - $width_int ),
        $number
    );
}

my $number = 0.001 + rand(1000);
say round_to_col( $number, 5);
产出可以是:

 11.18
 430.7
 0.842

您可以在
sprintf
之后使用
pack
。它可能不是一种计算效率高的方法,但实施和维护起来相对简单:

my $formattednumber = pack ('A5', sprintf("%5f", $number));

simbabque发布的答案并不涵盖所有情况,因此这是我的改进版本,以防任何人也需要类似的内容:

sub round_to_col {
  my ( $number, $width ) = @_;

  my $width_int = length int $number;
  my $sprintf; 
  print "round_to_col error: number longer than width" if $width_int > $width;
  $sprintf = "%d" if $width_int == $width;
  $sprintf = "% d" if $width_int == $width - 1;
  $sprintf = sprintf( '%%%d.%df', $width_int, $width - 1 - $width_int )
    if $width_int < $width -1;
  return sprintf( $sprintf , $number );
}
子轮到列{
我的($number,$width)=@;
my$width\u int=长度int$number;
我的$sprintf;
如果$width\u int>$width,则打印“舍入到列错误:数字大于宽度”;
$sprintf=“%d”如果$width\u int==$width;
$sprintf=“%d”如果$width\u int==$width-1;
$sprintf=sprintf('%%d.%df',$width\u int,$width-1-$width\u int)
如果$width_int<$width-1;
返回sprintf($sprintf,$number);
}

您应该确保您的示例已编译。不要在堆栈溢出编辑器中键入代码。复制并粘贴您的真实代码。@simbabque修复了它,没有复制粘贴,因为代码中的其他内容只会引起人们对问题的注意。问题是缺少引号。不过,只需使用
printf
而不是几行就可以获得更好的效果@simbabque首先你想要我代码中的内容,现在你不想要我代码中的内容。。。没有办法取悦你:D无论如何,我真的很喜欢你在回答中的方法,我从来没有想过,然后我继续发表了一个不完整的答案。。。我真可耻实际上我只是想编译你的代码,更不用说打印了为了给小数点留出空间,我不得不将5替换为4,你可能想在那个地方写$width,所以我把$width-1放在5的位置上,但这样做效果很好,谢谢。@fifaltra,对了,我把它修好了。谢谢现在你可以输入
5
,它将给出1+点+3,2+点+2,依此类推。很好地发现了它。它不会按要求旋转。它只是砍下来的。最初我想使用外部的
sprintf“%.5s”
,但它也会去掉小数。例如,对于
$number=661.887709350259
,输出应该是
661.9
,但是这种方法以及前面提到的
sprintf
,都会给出
661.8
,而不是四舍五入到小数点。你说得对。我很匆忙地阅读了这个问题,这是我的错。谢谢你的慈善评论。嗯,我试着在perldoc.perl.org上阅读
pack
,但我还是不太明白它在这里做什么。它是在前五个字符之后才被截断的吗?(我真的不介意不舍入,我在问题中说了舍入,但因为我们处理的是随机数,所以它没有那么重要)
pack
unpack
有很多用途,非常适合进行输入和输出转换,但上面的示例只是一个纯文本输出。”“A”是ASCII文本,5表示5个字符。这意味着如果它小于5,它将用空格填充它。如果更多,它将切掉尾随字符。在读取或写入固定宽度输出时,它是我最喜欢的工具之一。一定要读@simbaque的评论。虽然这对于本例可能无关紧要,但在使用此特定构造时,这是一个重要的考虑因素。