in reply to Printing large numbers with commas to show thousands groups.
Of course, there are plenty of potential pitfalls to this simple approach
Here's another approach to that without invocation of a sprintf binary, so no shell danger. Simply interpolate the "babycart operator" @{[]} into the format for any %'d conversion, call sprintf, then eval the result as a string. So something like
cprintf "There are at least %'d ways to do it!\n", 42e6;
will effectively result in
printf "There are at least @{[commify('%d')]} ways to do it!\n", 42e6;
with the difference that, unlike printf, the interpolation is done before the expansion of @{[]}
(printf evaluates the expansion first, i.e. it calls commify with a literal '%d', and then interpolates the value. Bug?)
but without the @{[]} evaluation being done at the time the format is assembled.
All other perl sprintf conversions and flags can be used within the format.
This does the trick:
sub commify { local $_ = shift; my $spc = ''; s/^(\s+)// and $spc = $1; # trim and save leading sp +ace my $adj = 0; $adj++ while s/^([-+]?\d+)(\d{3})/$1,$2/; $spc =~ s/.{$adj}//; # adjust space for commas added s/\s{0,$adj}$// if /\s$/; # adjust right padding return $spc . $_; } sub cprintf { (my $format = shift) =~ s{ \%(['+0-9.-]+)?([df]) # capture all valid %d and %f flags +and modifiers }{ my $p = $1; my $c = $2; $p =~ s/'// ? "\@{[commify('%$p$c')]}" : "%$p$c" }gex; my $str = sprintf $format, @_; print eval "\"$str\""; } cprintf "%+'012d\n", 1e6; cprintf "<%-'12.6d>\n", 1e6; cprintf "<%-+12.6'd>\n", 1e6; cprintf "<%+12.6'd>\n", -1e6; cprintf "<%+12.6d>\n", -1e6; cprintf "<%+12.2'f>\n", 1234.5; cprintf "There are at least %'d ways to do it!\n", 42e6; __END__ +00,001,000,000 <1,000,000 > <+1,000,000 > < +1,000,000> < -1,000,000> < -1000000> < +1,234.50> There are at least 42,000,000 ways to do it!
Of course, neither your nor my approach works for the printf FILEHANDLE FORMAT, LIST form of printf.
update: fixed format substitution
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Printing large numbers with commas to show thousands groups.
by Anonymous Monk on Dec 27, 2019 at 23:47 UTC | |
by shmem (Chancellor) on Dec 28, 2019 at 00:46 UTC | |
by Anonymous Monk on Dec 30, 2019 at 18:54 UTC |