in reply to sprintf and arrays of unknown (in advance) length

Hi, your problem description is not very clear. I think you are saying that you want to be able to handle arrays of varying lengths with a single sprintf statement. If so, you can always use the result of an expression as the format:

use strict; use warnings; my @slow_day = ( 4, 1..4 ); my @busy_day = ( 12, 1..12 ); for my $report ( \@slow_day, \@busy_day ) { my ( $total, @sales ) = @{ $report }; my $fmt = 'Total: $%2d Sales:' . ' $%.02f' x scalar(@sales); print sprintf($fmt, $total, @sales), "\n"; } __END__
Output:
$ perl 1223893.pl Total: $ 4 Sales: $1.00 $2.00 $3.00 $4.00 Total: $12 Sales: $1.00 $2.00 $3.00 $4.00 $5.00 $6.00 $7.00 $8.00 $9.0 +0 $10.00 $11.00 $12.00
Similarly you can examine the list and use the longest element length as a padding value, etc.

As to your second question: What happens when perl ... "runs out" of parameters (there are more variables to print than parameters in the format) ... Well, what happens when you try it? You can just use a one-liner for that:

$ perl -Mstrict -wE 'say sprintf("%s", qw/two strings/);'

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: sprintf and arrays of unknown (in advance) length
by choroba (Cardinal) on Oct 12, 2018 at 04:56 UTC
    > What happens when perl ... "runs out" of parameters

    Note that C behaves the same, but bash doesn't:

    $ printf '[%s]' two strings [two][strings]

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Curious: I couldn't get an example C program calling printf("%s\n", "two", "strings"); to crash or display any errors under Valgrind or -fsanitize=address -fsanitize=undefined even with full optimization and with omitted frame pointers, despite it being undefined behaviour.

      Not passing enough arguments in C for %s, though, causes a crash pretty quickly, because printf tries to interpret as a pointer something that was left on the stack from a previous function call, whatever it was. I got a lucky (null) a few times (stack had been filled with zeroes, and some C libraries handle NULL for %s as a special case, which is not required by the standard), then crashed on a different run when it tried to dereference address 0x1.