Как включить переменную в выражение Perl printf?

Как включить переменную в выражение printf?

вот мой пример:

printf "%${cols}s", $_;

здесь $cols - количество столбцов и $_ - это строка.

оператор приводит к предупреждению" недопустимое преобразование".

проблема в том, что я забыл проглотить переменную. Гах. Поблагодарить каждого.

6 ответов


я понял вашу конкретную проблему. Ваш код верен. Впрочем, я полагаю ... --2--> может быть число, считанное с пользовательского ввода, скажем так:

my $cols = <STDIN>;

это работает, и в числовом контексте $cols появится номер, но проблема в том, что $cols не появляется в числовом контексте здесь. Это в контексте строки, Что означает, что вместо расширения до "%5s", строка формата расширяется до "%5\ns". Новая линия там портит строка формата.

изменить код, где вы читаете $cols для этого:

chomp(my $cols = <STDIN>);

см. документацию на chomp, поскольку вы можете использовать его для другого чтения ввода.


ваша интерполированная переменная $cols похоже, что это должно быть число, скажем, 10, так что

"%${cols}s"

должен интерполироваться и быть эквивалентен

"%10s"

что является допустимой строкой формата.

Если же $cols было что-то другое чем число или допустимая строка формата, вы получите предупреждение.

например, если:

$cols = "w";

что бы "%ws" как строка формата-давая ошибку вы цитата:

Invalid conversion in printf: "%w"

действительная информация о формате может быть найдена здесь.


всегда использовать * в вашем спецификаторе формата однозначно указать переменную ширину! Это похоже на совет использовать printf "%s", $str, а не printf $str.

С perlfunc документация на sprintf:

(минимальная) ширина

аргументы обычно форматируются так, чтобы они были только такими широкими, как требуется для отображения заданного значения. Вы можете переопределить ширину, поместив здесь число, или получить ширину из следующего аргумент (с *) или из указанного аргумента (например,*2$):

printf '<%s>', "a";       # prints "<a>"
printf '<%6s>', "a";      # prints "<     a>"
printf '<%*s>', 6, "a";   # prints "<     a>"
printf '<%*2$s>', "a", 6; # prints "<     a>"
printf '<%2s>', "long";   # prints "<long>" (does not truncate)

если ширина поля, полученные через * отрицательно, он имеет тот же эффект, что и - флаг: слева-обоснование.

например:

#! /usr/bin/perl

use warnings;
use strict;

my $cols = 10;
$_ = "foo!";
printf "%*s\n", $cols, $_;
print "0123456789\n";

выход:

      foo!
0123456789

С warnings pragma enabled, вы увидите предупреждения для нечисловых аргументов ширины.


ваш текущий метод должен работать

perl -e'my $cols=500; $_="foo"; printf "%${cols}s\n\n", $_;'

Кажется, что для меня работает следующее:

#!/bin/perl5.8 -w
use strict;
my $cols = 5;
my $a = "3";
printf "%${cols}d\n", $a;

доходность

28$ ./test.pl
    3

29$ 

Я не могу воспроизвести вашу проблему. Следующий код отлично работает:

use strict;
use warnings;

my $cols=40;
while (<>) {
    printf "%${cols}s\n", $_;
}

он печатает любую входную строку, используя не менее 40 столбцов ширины.