2010-03-16 64 views
137

Sé que puede imprimir con printf() y puts(). También puedo ver que printf() le permite interpolar variables y formatear.¿Cuál es la diferencia entre printf() y puts() en C?

Es puts() simplemente una versión primitiva de printf(). ¿Debe usarse para todos los posibles printf() sin interpolación de cuerdas?

+32

Solo una nota sobre el uso de printf en lugar de poner: nunca, nunca haga una 'printf (variable)' para imprimir una cadena. Use 'puts (variable)' o 'printf ("% s ', variable) '. Existe un riesgo de seguridad al usar una cadena de formato variable: si la variable puede ser escrita por un atacante, pueden atacar el programa usando cadenas de formato. –

+1

[** puts() vs printf() - C/C++ Answers **] (http://bytes.com/topic/c/answers/527094-puts-vs-printf) –

Respuesta

109

puts es más simple que printf pero tenga en cuenta que el primero añade automáticamente una nueva línea. Si eso no es lo que desea, puede fputs su cadena a stdout o usar printf.

+4

Creo que también es importante mencionar los argumentos adicionales printf toman para agregar variables adicionales en la cadena de salida. – Erutan409

11

Derecho, printf podría considerarse como una versión más potente de puts. printf proporciona la capacidad de formato de las variables de salida utilizando especificadores de formato tales como %s, %d, %lf, etc ...

8
int puts(const char *s); 

puts() escribe la cadena s y un salto de línea final a la salida estándar.

int printf(const char *format, ...); 

La función printf() escribe en stdout, bajo el control de una cadena de formato que especifica cómo los argumentos posteriores son convertidos para la salida.

Aprovecharé esta oportunidad para pedirte que leas la documentación.

11

En mi experiencia, printf() arrastra en más código que puts() independientemente de la cadena de formato.

Si no necesito el formateo, no utilizo printf. Sin embargo, fwrite a stdout funciona mucho más rápido que puts.

static const char my_text[] = "Using fwrite.\n"; 
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout); 

Nota: por comentarios, '\ 0' es una constante entera. La expresión correcta debe ser sizeof(char) según lo indicado por los comentarios.

+2

"fwrite to stdout funciona mucho más rápido que puts." - ¿Cuál podría ser posiblemente la razón? –

+5

@AntonyHatchkins Normalmente no es "mucho" más rápido. puts() , sin embargo, tiene que realizar una llamada strlen() cada vez en la cadena, mientras que si se conoce el tamaño con fwrite() se puede evitar. Eso es prácticamente la única contribución real a una diferencia de rendimiento. – Wiz

+6

Esta respuesta es incorrecta. ''\ 0'' tiene tipo' int', por lo que en la mayoría de s y esto imprime 'Usando fwrit'. Si desea imprimir 1 byte menos, simplemente use 1. 'sizeof (char)', que es probable que lo que pretendía aquí, se garantiza que sea 1. –

5

La función printf() se utiliza para imprimir cadenas y variables en la pantalla mientras que la función puts() solo le permite imprimir una cadena solo en su pantalla.

26

Además de formatear, puts devuelve un entero no negativo si es exitoso o EOF si no lo logra; mientras que printf devuelve la cantidad de caracteres impresos (sin incluir el nulo final).

70

(Esto se señala en un comentario de Zan Lynx, pero creo que merece una respuesta, dado que la respuesta aceptada no lo menciona).

La diferencia esencial entre puts(mystr); y printf(mystr); es que en este último el argumento se interpreta como una cadena formato.El resultado será a menudo el mismo (excepto la nueva línea añadida) si la cadena no contiene ningún carácter de control (%) pero si no puede confiar en eso (si mystr es una variable en lugar de literal) debe no usarlo

Así que, por lo general es peligroso -y mal- conceptualmente utilizar una variable para el primer argumento de printf:

char * myMessage; 
    // ... myMessage gets filled at runtime with some unpredictable content 
    printf(myMessage); // WRONG! (what if myMessage contains a '%' char?) 
    puts(myMessage); // correct 
    printf("%s\n",myMessage); // equivalent to the above, perhaps less efficient 

Lo mismo se aplica a fputs vs fprintf (pero no fputs añadir el salto de línea).

+0

¿De qué forma el uso de 'printf()' sería menos eficiente? ¿En tiempo de ejecución? En tiempo de compilación? – franklin

+8

@franklin en tiempo de ejecución, porque 'printf' necesita analizar la cadena de formato. Sin embargo, esto normalmente debería ser irrelevante. Además, un compilador inteligente podría optimizar esto, y reemplazar el 'printf' con una llamada a' puts' – leonbloy

15

En casos simples, el compilador convierte las llamadas a printf() en llamadas al puts().

Por ejemplo, el siguiente código se compilará con el código de ensamblaje que muestro a continuación.

#include <stdio.h> 
main() { 
    printf("Hello world!"); 
    return 0; 
} 
push rbp 
mov rbp,rsp 
mov edi,str.Helloworld! 
call dword imp.puts 
mov eax,0x0 
pop rbp 
ret 

En este ejemplo, solía GCC versión 4.7.2 y compilado la fuente con gcc -o hello hello.c.

+7

¿Y qué pasa con la nueva línea que coloca en stdout? – zubergu

+0

Debería haber sido '' printf ("¡Hola mundo! \ N"); '' gcc de hecho lo traduce a puts. Dado que es un mensaje antiguo, lo editaré yo mismo. –

+2

¿Cómo leíste el código de ensamblado después de compilar el código C? –

1

Al comparar puts() y printf(), a pesar de que su consumo de memoria es casi el mismo, puts() toma más tiempo en comparación con printf().

2

puts es la opción simple y agrega una nueva línea al final y printf escribe la salida de una cadena formateada. Documentación para puts: http://linux.die.net/man/3/puts y para printf: http://linux.die.net/man/3/printf

yo recomendaría usar sólo printf ya que esto es más consistente que el método de conmutación, es decir si está debbugging es menos doloroso para buscar todas las printfs que pone y printf. La mayoría de las veces también desea generar una variable en sus impresiones, por lo que puts se usa principalmente en código de ejemplo.

Cuestiones relacionadas