http://qs1969.pair.com?node_id=24616

zdog has asked for the wisdom of the Perl Monks concerning the following question:

Is there any way I can set a length for a string?

So if I say,

my $string = "Hello"; print "$string;";

and set the length to 10, it prints out as

Hello         ;

rather than

Hello;

Thanx.

Zenon Zabinski | zdog | zdog7@hotmail.com

Replies are listed 'Best First'.
Re: A Set String Legngth
by young perlhopper (Scribe) on Jul 27, 2000 at 06:31 UTC
    you can use printf to pad your fields like this:

    printf("%-10s;", $string);
    the minus sign means the padding goes to the right of the string, so you will get the spaces between your string and the semicolon

    node 20519 has all the info you need about printf.

    Good luck,
    -Mark

Re: A Set String Length
by turnstep (Parson) on Jul 27, 2000 at 07:31 UTC
RE: Set String Length (benchmark)
by Russ (Deacon) on Jul 27, 2000 at 07:43 UTC
    print substr($String, 0, 10);
    <Update> SteveAZ98 is right: substr will not pad the string to a fixed length, if it is not longer than the desired width...</Update>

    Engaging in one of my favorite PM activities, I benchmarked pack vs. substr:

    timethese(1000000, { pack => q{ my $String = 'Russ is a stud'; $String = pack("A10", $S +tring)}, substr => q{ my $String = 'Russ is a stud'; $String = substr($String +, 0, 10)} });
    With these results:
    Benchmark: timing 1000000 iterations of pack, substr... pack: 7 wallclock secs ( 7.20 usr + 0.00 sys = 7.20 CPU) substr: 6 wallclock secs ( 6.67 usr + 0.01 sys = 6.68 CPU)
    I just love wasting time with benchmarks, perl golf, etc.

    Russ
    Brainbench 'Most Valuable Professional' for Perl

      I don't think substr is what he's looking for. That would chop off the end of the string, not pad it. But in the interest of benchmarking I ran the following.
      use Benchmark; my $str = 'hello'; timethese( 10000000, { 'pack' => q{ $str = pack("A10",$str); }, 'sprintf' => q{ $str = sprintf("%-10s",$str); }, });
      And got these results, not much of a difference.
      Benchmark: timing 10000000 iterations of pack, sprintf... pack: 18 secs (16.86 usr 0.00 sys = 16.86 cpu) sprintf: 18 secs (17.36 usr 0.00 sys = 17.36 cpu)
        Be careful with benchmark, your test is not a real test because your $str is lexical ... it is not defined in the 'pack' and 'sprintf' subroutines. You have to declare the lexical variable inside the routines. There can be significant differences between your test and a real test (although the pack and sprintf are still similar in performance):
        my $str = 'hello'; timethese( 1000000, { 'pack' => q{$str = pack("A10",$str); }, 'sprintf' => q{$str = sprintf("%-10s",$str); }, });
        Results:
        Benchmark: timing 1000000 iterations of pack, sprintf... pack: 3 wallclock secs ( 3.84 usr + 0.02 sys = 3.86 CPU) sprintf: 4 wallclock secs ( 4.24 usr + 0.00 sys = 4.24 CPU)
        The correct way:
        timethese( 1000000, { 'pack' => q{my $str = 'hello'; $str = pack("A10",$str); +}, 'sprintf' => q{my $str = 'hello'; $str = sprintf("%-10s",$str); +}, });
        Results:
        Benchmark: timing 1000000 iterations of pack, sprintf... pack: 6 wallclock secs ( 5.82 usr + 0.03 sys = 5.85 CPU) sprintf: 7 wallclock secs ( 6.80 usr + 0.01 sys = 6.81 CPU)
Re: A Set String Legngth
by perlmonkey (Hermit) on Jul 27, 2000 at 07:47 UTC
    And just to be obnoxious, you can use sprintf, like young perlhopper. $foo = sprintf("%-10s", "Hello"); or you can do $String .= " " x (10-length($String));
Re: A Set String Length
by ase (Monk) on Jul 27, 2000 at 14:08 UTC
    I actually did  $string .= " " x ($width-length($string)); in a script today - D'oh! Didn't even think about /printf | substr | unpack/ As it turned out, 'funny' things happen when <code>($width-length($s)<0</code)> so either you need to test for that (as I ended up doing) or do it another way -pack seems to be the best tool for what I'm doing -thanks for the fresh view.
    -ase
(zdog) Re: A Set String Length
by zdog (Priest) on Jul 27, 2000 at 06:29 UTC
    The subject should read "A Set String Length" rather than "A Set String Legngth".

    Sorry!

    And the -- start rolling in...

    Zenon Zabinski | zdog | zdog7@hotmail.com