The difference between "printf" and "print sprintf"

The following two simple perl programs have different types of behavior:

#file1 printf @ARGV; 

 #file2 $tmp = sprintf @ARGV; print $tmp; 

 $> perl file1 "hi %04d %.2f" 5 7.12345 #output: hi 0005 7.12 

 $> perl file2 "hi %04d %.2f" 5 7.12345 #output: 3 

Why is the difference? I thought these two programs are equivalent. I wonder if there is a way to make file2 (using "sprintf") behave like file1.

+7
perl printf
source share
3 answers

The built-in sprintf function has a prototype:

 $ perl -e 'print prototype("CORE::sprintf")' $@ 

It treats the first argument as a scalar. Since you provided the @ARGV argument, it was forcibly converted to a scalar, passing the number of @ARGV elements @ARGV .

Since the printf function must support the syntax printf HANDLE TEMPLATE,LIST , as well as printf TEMPLATE,LIST , it cannot support the prototype. Therefore, he always considers his arguments as a flat list and uses the first element in the list as a template.

One way to make its second script work correctly is to call it as

 $tmp = sprintf shift @ARGV, @ARGV 

Another difference between printf and sprintf is that print sprintf adds $\ to the output, and printf doesn't (thanks, ysth).

+8
source share

@ARGV contains the arguments passed in the form of a list script. printf accepts this list and prints it as is.

In the second example, you use sprintf with an array and assign it to a scalar. This basically means that it stores the length of the array in the $tmp variable. Therefore, you get 3 as a result.

+4
source share

From perl docs (jaypal said it already)

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

+3
source share

All Articles