Fixed value of field width in perl

I have a random number from 0.001 to 1000, and I need perl to print with a fixed column width of 5 characters. That is, if it is too long, it should be rounded, and if it is too short, it should be filled with spaces.

Everything I found on the Internet suggested using sprintf, but sprintf ignores the field width if the number is too large.

Is there any way to get perl for this?

What does not work:

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

EOF
+4
source share
3 answers

You need to dynamically identify the template sprintf. The number of decimal places depends on the number of digits on the left side of the decimal point.

This feature will do it for you.

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);

The conclusion could be:

 11.18
 430.7
 0.842
+4

pack sprintf. , :

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

The answer sent by simbabque does not apply to all cases, so this is my improved version, just in case, someone also needs something like this:

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 );
}
0
source

Source: https://habr.com/ru/post/1619872/


All Articles