10
sub do_printf { printf @_ } sub do_sprintf { print sprintf @_ } do_printf("%s\n", "ok"); # prints ok do_sprintf("%s\n", "ok"); # prints 2 

5 Answers 5

14

sprintf has prototype $@ while printf has prototype of @

Sign up to request clarification or add additional context in comments.

2 Comments

But does anyone have an idea, why? Generally such unobvious things mean there is some DWIM implied here.
A guess out of nowhere: sprintf has prototype ($@) because it can; printf has no prototype because (like print) it can take a bareword filehandle (e.g. printf FH "format", ... so it requires parser magic above and beyond what the prototype system can manage.
13

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.

Comments

9

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 

2 Comments

not able to figure how to re-write this, so that sprintf output has all array contents: sprintf("%-*s", 30,@arr)
@rajeev, perhaps sprintf("%-*s", 30, join(',', @arr))?
1

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

1 Comment

...OK, thank you for stating the obvious, and the answer to the poster's question is?...
1

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?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.