开发者

Why do printf and sprintf behave differently when only given an array?

sub do_printf  { printf @_ }
sub do_sprintf { print sprintf @_ }

do_printf("%s\n", "ok");  # prints ok
do_sprintf("%开发者_StackOverflow中文版s\n", "ok"); # prints 2


sprintf has prototype $@ while printf has prototype of @


From the perldoc on sprintf:

Unlike printf, sprintf does not do what you probably mean when you pass it an array as your first argument. The array is given scalar context, and instead of using the 0th element of the array as the format, Perl will use the count of elements in the array as the format, which is almost never useful.


See codeholic's and Mark's answers for the explanation as to why they behave differently.

As a workaround, simply do:

sub do_sprintf { print sprintf(shift, @_) }

Then,

sub do_printf  { printf @_ }
sub do_sprintf { print sprintf(shift, @_) }

do_printf("%s\n", "ok");  # prints ok
do_sprintf("%s\n", "ok2"); # prints ok2


They do different things. For printf the output is to a stream; for sprintf you want the string constructed. It handles the formatting (the f) of the print command. The main purpose for printf is to print out the value it constructs to a stream but with s(tring)printf(ormat) you're only trying to create the string, not print it.

printf returns the number of characters printed to a stream as feedback. Once characters are printed to a stream they've passed out of the logical structure of the program. Meanwhile, sprintf needs to hand you back a string. The most convenient way is as a return value--which because it is within the program structure can be inspected for length, or whether it contains any 'e's, or whatever you want.

Why shouldn't they behave differently?


sprintf evaluates the array in scalar context. Your array has two elements, so it evaluates as "2" (without a trailing \n).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜