Formatting stings with pack and printf in perl


I need to format a string with a fixed width so I've been playing with pack and sprintf to ad leading and trailing white space

my $string = "Hello";
print " short string $string;\n";

my $len;
($string,$len) = packString($string);

print "\nafter pack [$string] $len\n";
($string,$len) = sprintfString($string);
print "\nafter sprintf [$string] $len\n";

my $LongString ="Lorem ipsum dolor sit amet consectetuer auctor Curabitur.";

($LongString,$len)= packString($LongString);

print "\nLorem after pack [$LongString]  $len\n";
($LongString,$len)= sprintfString($LongString);

print "\nLorem after sprintf [$LongString]  $len\n";

print "\n6[";	
printf("%6s", 'foo'); 
print "] space B4 foo\n["; 
printf("%-6s", 'foo');
print "]space after foo\n[";	

printf("%-6s", "%10s", 'foo');
print "]space B4 & after  foo\n";

sub packString{
    my $string = shift;
    $string = pack("A20", $string);
    my $len = length($string);
    return ($string,$len);
sub sprintfString{
    my $string = shift;
    $string = sprintf("%20s", $string, "%20s" );
    my $len = length($string);
    return ($string,$len);

Open in new window

## output  from above
 short string Hello;

after pack [Hello               ] 20

after sprintf [Hello               ] 20

Lorem after pack [Lorem ipsum dolor si]  20

Lorem after sprintf [Lorem ipsum dolor si]  20

6[   foo] space B4 foo
[foo   ]space after foo
[%10s  ]space B4 & after  foo

Open in new window

1st  Which is the better option
2nd how do I add white space before and after foo on one line?
Who is Participating?
FishMongerConnect With a Mentor Commented:
Restating the same question without providing more info doesn't help much.

If the string is greater than 20 characters and you only want to output 20 of those characters, then the most obvious method would be to use the substr() function, next would be a regex and the 3rd would be the pack() function.  My choice would be the substr() function because it's the most self documenting of the three.

If the string is less than 20 characters and you want it left or right justified, then sprintf() would be the most obvious choice.  If it's going to be left justified, then the pack() function is also an option, but not if you need/want it right justified.

If it's under 20 chars and you want it space padded on both sides to a total length of 20, you need to determine how many spaces will be required and how much of that you want on each side.  Once that determination is made my choice would be to use sprintf() to output it.

So far I have not stated which is "best" because that is subjective.  "Best" in what way?  Readability, maintainability, performance, etc?  IMO, readability and maintainability should be the first consideration.  I look at performance issues after the script is written and profiled.  Premature optimizations are almost always a waste of effort.

If you are concerned with the performance, then write a short Benchmark test script comparing the difference between those methods and see which one is the fastest and by how much.
I'm not sure I understand why you want/need to use pack and  it's unclear what output you expect.

Please supply a more realistic sample of your input data, about 10 lines, and what you expect as output.
trevor1940Author Commented:

I need to output I string at a fixed length of 20 characters if necessary adding extra spaces  to the end or cutting the end off so i'm wondering what is the best way of doing it


    $string = pack("A20", $string);
    print "pack [$string]\n";

Open in new window

or sprintf
    $string = sprintf("%20s", $string );
    print "sprintf [$string]\n";

Open in new window

Output for both

pack [Hello               ] 

sprintf [Hello               ]

pack [Lorem ipsum dolor si]

sprintf [Lorem ipsum dolor si]

Open in new window

Which is the better option?

Taking it one step further If I need to add spaces at both begging and end how might I do this

 my $foo = 'foo';
printf("%-6s", "%10s", $foo';
output 6 spaces before & 10 after

[       foo          ]  ## brackets for show only

Open in new window

trevor1940Author Commented:
Thanx for explanation  

Apologies for  posting subjective question
As usual, FishMonger gave you a full explanation of options and I agree with what he said.

The way I'd do what you want would be:
$output = sprintf '%20s', substr($input, 0, 20);
# if you want left-justified, make it %-20s
# if you want center-justified, it gets more complicated

Open in new window

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.