The following two simple perl programs have different behaviors:
#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 had thought the two programs are equivalent. Wonder if there is a way to make file2 (using "sprintf") to behave like file1.
The function printf () is used to print the message along with the values of variables. printf (const char *str, ...); Welcome! The value of a : 24 The function sprintf () is also known as string print function. It do not print the string. It stores the character stream on char buffer.
printf is used to print text (string/ character stream) or/and values on standard output device. int printf (const char *format, ...); format provides the format of the text string which is going to print on the output device with the help of format specifiers like %s, %d, %f etc. ... provides the list of arguments to be print.
int sprintf (char *str, const char *string,...); The function fprintf () is known as format print function. It writes and formats the output to a stream.
int printf (const char* str, ...); int sprintf (char *str, const char *string,...); String print function instead of printing on console store it on char buffer which are specified in sprintf fprintf is used to print the string content in file but not on stdout console.
The builtin sprintf
function has a prototype:
$ perl -e 'print prototype("CORE::sprintf")'
$@
It treats the first argument as a scalar. Since you provided the argument @ARGV
, it was coerced into a scalar by passing the number of elements in @ARGV
instead.
Since the printf
function has to support the syntax printf HANDLE TEMPLATE,LIST
as well as printf TEMPLATE,LIST
, it cannot support a prototype. So it always treats its arguments as a flat list, and uses the first element in the list as the template.
One way to make it the second script work correctly would be to call it like
$tmp = sprintf shift @ARGV, @ARGV
Another difference between printf
and sprintf
is that print sprintf
appends $\
to the output, while printf
does not (thanks, ysth).
@ARGV
contains the arguments passed to the script in list form. printf
takes that list and prints it out as is.
In second example you are using sprintf
with the array and assigning it to scalar. Which basically means it stores the length of the array in your variable $tmp
. Hence you get 3
as output.
From the perl docs (jaypal said it already)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With