sub do_printf { printf @_ }
sub do_sprintf { print sprintf @_ }
do_printf("%s\n", "ok"); # prints ok
do_sprintf("%s\n", "ok"); # prints 2
Почему printf и sprintf ведут себя по-разному, когда заданы только массивы?
Ответ 1
В отличие от printf, sprintf не делает что вы, вероятно, имеете в виду при прохождении это массив в качестве вашего первого аргумента. Массив задается скалярным контекстом и вместо использования 0-го элемента массив как формат, Perl будет использовать количество элементов в массиве как формат, который почти никогда полезно.
Ответ 2
sprintf
имеет прототип [email protected]
, а printf
имеет прототип @
Ответ 3
См. ответы codeholic
и Mark
для объяснения того, почему они ведут себя по-другому.
Как обходной путь, просто выполните:
sub do_sprintf { print sprintf(shift, @_) }
Затем
sub do_printf { printf @_ }
sub do_sprintf { print sprintf(shift, @_) }
do_printf("%s\n", "ok"); # prints ok
do_sprintf("%s\n", "ok2"); # prints ok2
Ответ 4
Они делают разные вещи. Для printf
выход - поток; для sprintf
вы хотите, чтобы строка была построена. Он обрабатывает форматирование (f) команды печати. Основной целью printf
является распечатать значение, которое он создает для потока, но с помощью s (tring) printf (ormat) вы пытаетесь создать строку, а не печатать ее.
printf
возвращает количество символов, напечатанных в потоке в качестве обратной связи. Как только символы печатаются в поток, они перешли из логической структуры программы. Между тем, sprintf
нужно передать вам строку. Самый удобный способ - это как возвращаемое значение, которое, поскольку оно находится внутри структуры программы, может быть проверено на длину, или содержит ли оно какие-либо "e" или что угодно.
Почему они не должны вести себя по-другому?
Ответ 5
sprintf оценивает массив в скалярном контексте. В вашем массиве два элемента, поэтому он оценивается как "2" (без конечного\n).