Как я могу включать переменную в printf выражение?
Вот мой пример:
printf "%${cols}s", $_;
Где $cols
число столбцов и $_
строка.
Оператор приводит к "Недопустимому преобразованию" предупреждение.
Проблема закончила тем, что была, что я забыл громко жевать переменную. Gah. Спасибо все.
Я не могу воспроизвести вашу проблему. Следующий код работает нормально:
use strict;
use warnings;
my $cols=40;
while (<>) {
printf "%${cols}s\n", $_;
}
Он печатает любую входную строку, используя не менее 40 столбцов ширины.
-121--3772218- Интерполяционная переменная $ cols
должна быть числом, скажем 10, поэтому
"%${cols}s"
должна быть интерполирована и эквивалентна
"%10s"
, который является допустимым форматом последовательности.
Если бы $ cols
был чем-то другим , чем число или допустимый формат последовательности, вы бы получили предупреждение.
Например, если:
$cols = "w";
, что приведет к «% ws»
в качестве последовательности формата - с указанием ошибки вы цитируете:
Invalid conversion in printf: "%w"
Допустимые сведения о формате можно найти здесь .
-121--3772211- Я выяснил вашу конкретную проблему. Код правильный. Однако я полагаю, что $ cols
может быть числом, считанным из пользовательского ввода, скажем так:
my $cols = <STDIN>;
Это работает, и в числовом контексте $ cols
будет выглядеть как число, но проблема в том, что $ cols
не появляется в числовом контексте здесь. В последовательность контексте это означает, что вместо расширения до «% 5s»
формат последовательности расширяется до «% 5\ns»
. Новая линия там сковывает последовательность формата.
Измените код, в котором вы читаете $ cols
, на следующий:
chomp(my $cols = <STDIN>);
См. документацию по chomp
, так как ее можно использовать и для чтения других входных данных.
Мне кажется, что следующее работает:
#!/bin/perl5.8 -w
use strict;
my $cols = 5;
my $a = "3";
printf "%${cols}d\n", $a;
дает
28$ ./test.pl
3
29$
Ваша интерполированная переменная $cols
выглядит так, как будто она должна быть числом, скажем 10, поэтому
"%${cols}s"
должна интерполироваться и быть эквивалентной
"%10s"
что является допустимой строкой формата.
Однако если $cols
будет чем-то другим, чем число или допустимая форматная строка, то вы получите предупреждение.
Например, если:
$cols = "w";
в качестве строки формата будет "%ws"
, то возникнет ошибка, которую вы цитируете:
Invalid conversion in printf: "%w"
Информация о допустимом формате может быть найдена здесь.
Никто никогда не был уволен за выбор Java
-121--3302885- Использование double fun ()
, а не double (* fun) ()
является архаичной формой, которая действительна только в стандарте C и никогда в C++, и если я правильно помню, только при объявлении аргумента функции. (во многом как ary []
, что является законным для аргумента функции, но не для неинициализированной переменной)
Поскольку невозможно (в языке C) передать функцию по значению другой функции, компилятор просто принял двойную забаву ()
, чтобы обозначить указатель на функцию, которая вернула двойную.
Это действительно (но архаично. попал в немилость)
Всегда используйте *
в спецификаторе формата для однозначного указания переменной ширины! Это аналогично совету использовать printf «% s», $ str
, а не printf $ str
.
В документации по perlfunc на sprintf
:
(минимальная) ширина
Аргументы обычно форматируются так, чтобы иметь ширину, необходимую для отображения заданного значения. Можно переопределить ширину, поместив здесь число, или получить ширину из следующего аргумента (с помощью
*
) или из указанного аргумента (например, с помощью* 2 $
):printf «<% s >», «a»; # печатает «< a >» printf "<% 6s >", a "; # печатает" < a > " printf «<% * s >», 6, «a»; # печатает «< a >» printf '<% * 2 $ s >', «a», 6; # печатает «< a >» printf «» <% 2s > «», long; # печатает «» < long > «» (не усекается)
Если ширина поля, полученная с помощью
*
, отрицательна, она имеет тот же эффект, что и флаг-
: левое выравнивание.
Например:
#! /usr/bin/perl
use warnings;
use strict;
my $cols = 10;
$_ = "foo!";
printf "%*s\n", $cols, $_;
print "0123456789\n";
Вывод:
foo! 0123456789
При включенной прагматике предупреждений
появятся предупреждения для нечисловых аргументов ширины.
Ваш текущий метод должен работать
perl -e'my $cols=500; $_="foo"; printf "%${cols}s\n\n", $_;'
Я не могу воспроизвести вашу проблему. Следующий код работает нормально:
use strict;
use warnings;
my $cols=40;
while (<>) {
printf "%${cols}s\n", $_;
}
Он печатает любую строку ввода шириной не менее 40 столбцов.