Differenza tra fprintf, printf e sprintf?


233

Qualcuno può spiegare in inglese semplice sulle differenze tra printf, fprintfe sprintfcon esempi?

In che flusso è?

Sono davvero confuso tra i tre di questi durante la lettura di "Gestione dei file in C".


4
Sperimenta con loro scrivendo del codice di esempio. Questo è un modo molto semplice per capire chiaramente la differenza tra loro.
Nawaz,

14
Preferire snprintf () a sprintf () per evitare stupidi overflow del buffer.
Maxim Egorushkin,

3
Preferisci stream o Boost formattatori per evitare stupidi overflow del buffer e cattivi bug di tipo non sicuro
John Dibling

7
@Maxim, mentre sollevi un punto valido, prenderò la sicurezza sapendo che i miei buffer non stanno per traboccare ed esplodere la mia app a pezzi. Esaminerei mai queste funzioni solo se si dimostrasse che i flussi / formattatori boost stanno causando notevoli colli di bottiglia. :)
Moo-Juice

1
@Maxim: il punto è che non è necessario. Il mio codice non è un collo di bottiglia. 5 m / sec è il numero di messaggi inviati dallo scambio, non quanti siamo in grado di elaborare. Quindi perché ottimizzare prematuramente?
John Dibling,

Risposte:


238

In C, un "flusso" è un'astrazione; dal punto di vista del programma è semplicemente un produttore (flusso di input) o consumatore (flusso di output) di byte. Può corrispondere a un file su disco, a una pipe, al terminale o ad altri dispositivi come una stampante o tty. Il FILEtipo contiene informazioni sullo stream. Normalmente, non si scherza direttamente con FILEil contenuto di un oggetto, si passa semplicemente un puntatore ad esso alle varie routine di I / O.

Esistono tre flussi standard: stdinè un puntatore al flusso di input standard, stdoutè un puntatore al flusso di output standard ed stderrè un puntatore al flusso di output degli errori standard. In una sessione interattiva, i tre di solito si riferiscono alla tua console, anche se puoi reindirizzarli per puntare ad altri file o dispositivi:

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

In questo esempio, stdinora punta a inputfile.dat,stdout punta a output.txte stderrpunta a errors.txt.

fprintf scrive il testo formattato nel flusso di output specificato.

printfequivale a scrivere fprintf(stdout, ...)e scrive testo formattato ovunque il flusso di output standard stia attualmente puntando.

sprintfscrive il testo formattato in una matrice di char, anziché in un flusso.


4
"è semplicemente un produttore (flusso di input) o consumatore (flusso di output) di byte." Sono all'indietro? Un produttore non avrebbe creato (prodotto) qualcosa? Chiedere perché sinceramente non lo so.
Dave Voyles,

6
@DaveVoyles: questi sono dal punto di vista del tuo programma. Un flusso di input produce byte per la lettura del programma; un flusso di output consuma i byte prodotti dal tuo programma.
John Bode,

153

printfoutput allo stream di output standard ( stdout)

fprintfva a un handle di file ( FILE*)

sprintfva a un buffer assegnato. ( char*)


40

printf ("format", args) è usato per stampare i dati sullo standard output che è spesso un monitor per computer.

sprintf (char *, "format", args) è come printf. Invece di visualizzare la stringa formattata sull'output standard, ad esempio un monitor, memorizza i dati formattati in una stringa puntata dal puntatore char (il primo parametro). La posizione della stringa è l'unica differenza tra la sintassi di printf e sprint.

fprintf (FILE * fp, "format", args) è di nuovo come printf. Qui, invece di visualizzare i dati sul monitor o salvarli in una stringa, i dati formattati vengono salvati su un file a cui punta il puntatore del file che viene utilizzato come primo parametro di fprintf. Il puntatore al file è l'unica aggiunta alla sintassi di printf.

Se il file stdout viene utilizzato come primo parametro in fprintf, il suo funzionamento viene considerato equivalente a quello di printf.


24

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

fprintf viene utilizzato per l'output in streaming.

sprintf(buffer,...) viene utilizzato per formattare una stringa in un buffer.

Nota che c'è anche vsprintf, vfprintfevprintf


I vsapori non sono standard credo
John Dibling

8
I vsapori sono sicuramente nello standard C.
Fred Foo,

@larsmans: ah, ok. grazie per la correzione. A un certo punto questa domanda è stata taggata [c ++]
John Dibling il

2

Puoi anche fare cose molto utili con la funzione 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)

+1 davvero utile, ma tieni presente che si vsnprintftratta di una funzione non standard. La maggior parte delle implementazioni che ho visto implementano questo o qualcosa del genere, ma è specifico per l'implementazione.
John Dibling,

1
@larsmans menziona sopra che questo è, in effetti, una parte dello standard C, quindi lo riprendo
John Dibling

2
Cosa c'entra questo con C?
onemasse,

2

printf

  1. printf viene utilizzato per eseguire l'output sullo schermo.
  2. sintassi = printf("control string ", argument );
  3. Non è associato all'input / output del file

fprintf

  1. La fprintf utilizzata per eseguire l'operazione di scrittura nel file indicato dall'handle FILE.
  2. La sintassi è fprintf (filename, "control string ", argument );
  3. È associato all'input / output del file

Se questo è citato da qualche altra parte, è meglio citare la fonte con un link, ma sicuramente mantenere comunque il testo che hai citato qui.
SuperBiasedMan,

0

fprintfCiò è correlato agli stream in cui, come printfè un'istruzione simile fprintfma non correlata agli stream, fprintfè relativa ai file


0

sprintf: scrive i dati formattati in una stringa di caratteri in memoria anziché in stdout

La sintassi di sprintf è:

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

Qui,

String si riferisce al puntatore a un buffer in memoria in cui devono essere scritti i dati.

Il formato si riferisce al puntatore a una stringa di caratteri che definisce il formato.

Ogni elemento è una variabile o un'espressione che specifica i dati da scrivere.

Il valore restituito da sprintf è maggiore o uguale a zero se l'operazione ha esito positivo o in altre parole viene restituito il numero di caratteri scritti, senza contare il carattere null che termina e restituisce un valore inferiore a zero in caso di errore.

printf: stampa su stdout

La sintassi per printf è:

printf format [argument]…

L'unica differenza tra sprintf () e printf () è che sprintf () scrive i dati in un array di caratteri, mentre printf () scrive i dati su stdout, il dispositivo di output standard.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.