2010-03-20 16 views
10
sub do_printf { printf @_ } 
sub do_sprintf { print sprintf @_ } 

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

Respuesta

13

Desde el perldoc on sprintf:

A diferencia de printf, sprintf no hace lo que probablemente significa que cuando se pasa es una matriz como su primer argumento. La matriz se da contexto escalar, y en lugar de utilizar el elemento 0 ª de la matriz como el formato, Perl usará el recuento de elementos en la matriz como el formato, que es casi nunca útil.

1

sprintf evalúa la matriz en contexto escalar. Su matriz tiene dos elementos, por lo que se evalúa como "2" (sin un seguimiento \ n).

+1

... OK, gracias por decir lo obvio, y la respuesta a la pregunta del cartel es? ... – vladr

14

sprintf tiene un prototipo [email protected] mientras printf tiene prototipo de @

+0

+1 Una mejor respuesta técnica que la mía :-) – crazyscot

+1

Pero, ¿alguien tiene una idea, por qué? En general, tales cosas no obvias significan que hay algo de DWIM implícito aquí. – codeholic

+7

A adivinar de la nada: 'sprintf' tiene el prototipo' ($ @) 'porque puede; 'printf' no tiene ningún prototipo porque (como' print') puede tomar una manejador de archivos (por ejemplo, 'printf FH' format ', ... 'por lo que requiere magia del analizador más allá de lo que el sistema prototipo puede administrar. – hobbs

9

respuestas Ver codeholic 's y Mark' s para la explicación de por qué se comportan de manera diferente.

Como solución alternativa, sólo tiene que hacer:

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

Entonces,

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

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

no puede para saber cómo volver a escribir esto, de modo que la salida sprintf tenga todos los contenidos de la matriz: 'sprintf ("% - * s ", 30, @ arr)' – rajeev

+0

@rajeev, quizás 'sprintf ("% - * s ", 30 , join (',', @arr)) ' – vladr

2

que hacen cosas diferentes. Para printf la salida es a una secuencia; para sprintf desea que la cuerda se construya. Maneja el formato (f) del comando de impresión. El objetivo principal de printf es imprimir el valor que construye en una secuencia, pero con s (tring) printf (ormat) solo intenta crear la cadena, no imprimirla.

printf devuelve la cantidad de caracteres impresos en una secuencia como comentarios. Una vez que los caracteres se imprimen en una secuencia, se han eliminado de la estructura lógica del programa. Mientras tanto, sprintf necesita devolverle una cadena. La forma más conveniente es como un valor de retorno, que debido a que está dentro de la estructura del programa puede inspeccionarse por su longitud, o si contiene alguna 'e', ​​o lo que usted desee.

¿Por qué no debería se comportan de manera diferente?

Cuestiones relacionadas