Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

printf centering 2

Status
Not open for further replies.

arcnon

Programmer
Aug 12, 2003
242
US
anyone know a way to center a string in between spaces with printf or grep etc or better than what I have

$kick = 0;
$column = 13;
$string = "abc";
$newString = "";
$lens = length($string);
$splitme = $column - $lens;
$mo = ($splitme - ($splitme % 2)) / 2;

for($count = 0; $count < $column; $count++){

if ($count < $mo){
$newString = "$newString ";
}
elsif($count < ($splitme + $mo) && $kick == 0){
$newString = "$newString" . $string;
$kick = 1;
}
else{
$newString = "$newString ";
}
}
print ">$newString<";
#' abc '

 
Code:
my $column = 13;
my $string = "abc";
my $spaces = ' ' x int(($column - length($string)) / 2);
print ">", $spaces, $string, $spaces, "<\n"; [b]#with print[/b]
printf ">%s%s%s<\n", ($spaces, $string, $spaces); [b]#with printf[/b]
Of course, you need to have a plan if $string is longer than $column.
 
This is a little nicer. Handles the string-too-long issue (by truncation) and allows an optional character to pad on other than space.

Code:
my $column = 13;
my @strings = qw(abc qrxz fghijk lmnop dgterw xx yyyy abcdefghijklmno);
for my $string (@strings) {
    print ">", pad($string, $column), "<\n";
}

sub pad {
    # Return $str centered in a field of $col $padchars.
    # $padchar defaults to ' ' if not specified.
    # $str is truncated to len $column if too long.

    my ($str, $col, $padchar) = @_;
    $padchar = ' ' unless $padchar;
    my $strlen = length($str);
    $str = substr($str, 0, $col) if ($strlen > $col);
    my $fore = int(($col - $strlen) / 2);
    my $aft = $col - ($strlen + $fore);
    $padchar x $fore . $str . $padchar x $aft;
}

Output:
>     abc     <
>    qrxz     <
>   fghijk    <
>    lmnop    <
>   dgterw    <
>     xx      <
>    yyyy     <
>abcdefghijklm<
 
Or you use the format perl offers (but for some reason barely ever used).
 
that is kinda the premise to this. format throws errors(even the examples ie from books, websites) so I am writing something like format for me to use for template interfaces to my command line apps.

this centering issue... just seems there should be an easier way.
 
that is a nice solution mike better than what I have
 
Thanks, arcnon.
Here's an improved version. This factors out the construction of the strings to pad with to another function, makestr. Note that optional $padchar can now be a multi-char string.

Code:
my $column = 13;
my @strings = qw(This is centered in a field of 13 columns);
for my $string (@strings) {
    print ">", pad($string, $column, [b]'-^~'[/b]), "<\n";
}

sub makestr {
    # Returns a string of $c of length $l.
    # $c may be a multi-char string
    # Returns an empty string if $c is ''.

    my ($c, $l) = @_;
    my $clen = length($c);
    $clen? $c x int($l / $clen) . substr($c, 0, $l % $clen): '';
}

sub pad {
    # Return $str centered in a field of $col $padchars.
    # $padchar defaults to ' ' if not specified.
    # $str is truncated to len $col if too long.

    my ($str, $col, $padchar) = @_;
    $padchar = ' ' unless length($padchar);
    $str = substr($str, 0, $col) if length($str) > $col;
    my $strlen = length($str);
    my $fore = int(($col - $strlen) / 2);
    my $aft = $col - ($strlen + $fore);
    makestr($padchar, $fore) . $str . makestr($padchar, $aft);
}

Output:
>-^~-This-^~-^<
>-^~-^is-^~-^~<
>-^centered-^~<
>-^~-^in-^~-^~<
>-^~-^~a-^~-^~<
>-^~-field-^~-<
>-^~-^of-^~-^~<
>-^~-^13-^~-^~<
>-^~columns-^~<
 
Code:
format centredText =
@||||||||||||
$line
.

@words = qw(abc qrxz fghijk lmnop dgterw xx yyyy abcdefghijklm);

foreach $line (@words) {
  $~ = centredText;
  write;
}

output:-

Code:
[red]     abc
    qrxz
   fghijk
    lmnop
   dgterw
     xx
    yyyy
abcdefghijklm[/red]


Kind Regards
Duncan
 
Thanks, Duncan. I've never learned to use Perl's format. When I was first learning Perl, I thought, "This isn't something I need right now," and since then I've very rarely seen it used, so I never got back to it.

Can you comment on why it seems to be used so infrequently, or on arcnon's observation that "format throws errors(even the examples ie from books, websites)"?

Also curious, can it fill with something other than blanks, or with multi-char strings, like in my last output example?
 
back before I upgraded to jaguar. format was my standard for my commandline apps. But since my upgrade it started throwing errors. It has been very difficult to live without. I have googled for a solution but I haven't come up with anything yet. I have been tempted just to try a reinstall but that is such a hassle. I wish reinstalling for a mac was a easy as it use to be. Burn a few CDs, format, install update the HD drivers, and copy it back.

Now with 400+gigs exporting databases, getting the applications reinstalled, software updates. checking permissions blah blah. It eats about 18 hours and is a hair pulling experience.
 
This works pretty well without needing format

I have left the 'padding' character as a hash character so it is visually obvious when it is doing so

Code:
$padL = ">";
$padR = "<";

@words = qw(abc qrxz fghijk lmnop dgterw xx yyyy abcefghijklm);

$shortest = length($words[0]);

foreach $line (@words) {
  $shortest = length($line) if (length($line) < $shortest);
   $longest = length($line) if (length($line) > $longest);
}

$difference = $longest - $shortest;

print "\$longest:$longest - \$shortest:$shortest = $difference\n\n";

foreach $line (@words) {
  print "$padL" x (($longest - length($line)) / 2);
  print $line;
  print "$padR" x (($longest - length($line)) / 2);
  print "#" if (length($line) / 2 != int(length($line) / 2)); # padding
  print "\n";
}

output:-

Code:
[blue]$longest:12 - $shortest:2 = 10

>>>>abc<<<<#
>>>>qrxz<<<<
>>>fghijk<<<
>>>lmnop<<<#
>>>dgterw<<<
>>>>>xx<<<<<
>>>>yyyy<<<<
abcefghijklm
[/blue]


Kind Regards
Duncan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top