¿Diferencia entre fprintf, printf y sprintf?

233

¿Alguien puede explicar con simples Inglés sobre las diferencias entre printf, fprintfy sprintfcon ejemplos?

¿En qué corriente está?

Estoy realmente confundido entre estos tres al leer sobre "Manejo de archivos en C".

Vishwanath Dalvi
fuente
44
Experimente con ellos escribiendo un código de muestra. Esa es una manera muy fácil de entender claramente la diferencia entre ellos.
Nawaz
14
Prefiera snprintf () a sprintf () para evitar desbordamientos de búfer tontos.
Maxim Egorushkin
3
Prefiera transmisiones o formateadores Boost para evitar desbordamientos de búfer tontos y errores desagradables de tipo inseguro
John Dibling
77
@Maxim, mientras planteas un punto válido, tomaré la seguridad de saber que mis búferes no se desbordarán y explotarán mi aplicación en pedazos. Solo miraría estas funciones si se demostrara que los formadores de stream / boost causan cuellos de botella notables. :)
Moo-Juice
1
@Maxim: El punto es que no hay necesidad. Mi código no es un cuello de botella. 5 m / seg es cuántos mensajes envía el intercambio, no cuántos somos capaces de procesar. Entonces, ¿por qué optimizar prematuramente?
John Dibling

Respuestas:

238

En C, un "flujo" es una abstracción; desde la perspectiva del programa, es simplemente un productor (flujo de entrada) o consumidor (flujo de salida) de bytes. Puede corresponder a un archivo en el disco, a una tubería, a su terminal o a algún otro dispositivo, como una impresora o tty. El FILEtipo contiene información sobre la secuencia. Normalmente, no se mete con FILEel contenido de un objeto directamente, simplemente le pasa un puntero a las diversas rutinas de E / S.

Hay tres flujos estándar: stdines un puntero al flujo de entrada estándar, stdoutes un puntero al flujo de salida estándar y stderres un puntero al flujo de salida de error estándar. En una sesión interactiva, los tres generalmente se refieren a su consola, aunque puede redirigirlos para que apunten a otros archivos o dispositivos:

$ myprog < inputfile.dat > output.txt 2> errors.txt

En este ejemplo, stdinahora apunta a inputfile.dat, stdoutapunta a output.txty stderrapunta a errors.txt.

fprintf escribe texto formateado en la secuencia de salida que especifique.

printfes equivalente a escribir fprintf(stdout, ...)y escribe texto formateado en cualquier lugar donde apunte actualmente la secuencia de salida estándar.

sprintfescribe texto formateado en una matriz de char, en lugar de una secuencia.

John Bode
fuente
44
"es simplemente un productor (flujo de entrada) o consumidor (flujo de salida) de bytes". ¿Son estos al revés? ¿No crearía un productor (salida) algo? Preguntando porque realmente no lo sé.
Dave Voyles
66
@DaveVoyles: son desde la perspectiva de su programa. Una secuencia de entrada produce bytes para que su programa los lea; una secuencia de salida consume los bytes producidos desde su programa.
John Bode
153

printfsalidas a la secuencia de salida estándar ( stdout)

fprintfva a un identificador de archivo ( FILE*)

sprintfva a un búfer que asignaste. ( char*)

Jugo De Moo
fuente
40

printf ("formato", args) se utiliza para imprimir los datos en la salida estándar, que a menudo es un monitor de computadora.

sprintf (char *, "format", args) es como printf. En lugar de mostrar la cadena formateada en la salida estándar, es decir, un monitor, almacena los datos formateados en una cadena señalada por el puntero de caracteres (el primer parámetro). La ubicación de la cadena es la única diferencia entre printf y la sintaxis de sprint.

fprintf (FILE * fp, "format", args) es como printf nuevamente. Aquí, en lugar de mostrar los datos en el monitor o guardarlos en alguna cadena, los datos formateados se guardan en un archivo al que apunta el puntero de archivo que se usa como el primer parámetro para fprintf. El puntero de archivo es la única adición a la sintaxis de printf.

Si se utiliza el archivo stdout como primer parámetro en fprintf, su funcionamiento se considera equivalente al de printf.

Rubal
fuente
24

printf(...)es equivalente a fprintf(stdout,...).

fprintf se usa para enviar a la transmisión.

sprintf(buffer,...) se usa para formatear una cadena en un búfer.

Tenga en cuenta que también hay vsprintf, vfprintfyvprintf

VGE
fuente
Los vsabores no son estándar, creo
John Dibling
8
Los vsabores están ciertamente en el estándar C.
Fred Foo
@larsmans: ah, está bien. gracias por la corrección. Esta pregunta fue etiquetada en un momento [c ++]
John Dibling
2

También puede hacer cosas muy útiles con la función vsnprintf ():

$ cat test.cc
#include <exception>
#include <stdarg.h>
#include <stdio.h>

struct exception_fmt : std::exception
{
    exception_fmt(char const* fmt, ...) __attribute__ ((format(printf,2,3)));
    char const* what() const throw() { return msg_; }
    char msg_[0x800];
};

exception_fmt::exception_fmt(char const* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(msg_, sizeof msg_, fmt, ap);
    va_end(ap);
}

int main(int ac, char** av)
{
    throw exception_fmt("%s: bad number of arguments %d", *av, ac);
}

$ g++ -Wall -o test test.cc

$ ./test
terminate called after throwing an instance of 'exception_fmt'
  what():  ./test: bad number of arguments 1
Aborted (core dumped)
Maxim Egorushkin
fuente
+1 es útil, pero ten en cuenta que vsnprintfes una función no estándar. La mayoría de las implementaciones que he visto implementan esto o algo similar, pero es específico de la implementación.
John Dibling
1
@larsmans menciones anteriormente que este es, de hecho, una parte de la norma C, por lo que lo retiro
John Dibling
2
¿Qué tiene esto que ver con C?
onemasse
2

printf

  1. printf se utiliza para realizar la salida en la pantalla.
  2. sintaxis = printf("control string ", argument );
  3. No está asociado con la entrada / salida de archivos

fprintf

  1. El fprintf solía realizar una operación de escritura en el archivo señalado por el identificador FILE.
  2. La sintaxis es fprintf (filename, "control string ", argument );
  3. Está asociado con la entrada / salida del archivo
Amit Vasava
fuente
Si esto se cita desde otro lugar, es mejor citar la fuente con un enlace, pero definitivamente aún conserva el texto que ha citado aquí.
SuperBiasedMan
0

fprintfEsto está relacionado con las secuencias donde, como printfes una declaración similar fprintfpero no relacionada con las secuencias, es decir, fprintfestá relacionada con el archivo

kavamsi12
fuente
0

sprintf: escribe datos formateados en una cadena de caracteres en la memoria en lugar de stdout

La sintaxis de sprintf es:

#include <stdio.h>
int sprintf (char *string, const char *format
[,item [,item]…]);

Aquí,

La cadena se refiere al puntero a un búfer en la memoria donde se escribirán los datos.

Formato se refiere al puntero a una cadena de caracteres que define el formato.

Cada elemento es una variable o expresión que especifica los datos a escribir.

El valor devuelto por sprintf es mayor o igual a cero si la operación es exitosa o, en otras palabras, el número de caracteres escritos, sin contar el carácter nulo final, se devuelve y devuelve un valor menor que cero si ocurrió un error.

printf: imprime en stdout

La sintaxis para printf es:

printf format [argument]…

La única diferencia entre sprintf () y printf () es que sprintf () escribe datos en una matriz de caracteres, mientras que printf () escribe datos en stdout, el dispositivo de salida estándar.

Fahad Ali
fuente