Différence entre fprintf, printf et sprintf?


233

Quelqu'un peut -il expliquer en anglais simple sur les différences entre printf, fprintfet sprintfavec des exemples?

Dans quel flux est-il?

Je suis vraiment confus entre les trois lors de la lecture de "Gestion des fichiers en C".


4
Essayez-les en écrivant un exemple de code. C'est un moyen très facile de comprendre clairement la différence entre eux.
Nawaz

14
Préférez snprintf () à sprintf () pour éviter les débordements idiots de tampon.
Maxim Egorushkin du

3
Préférez les flux ou les formateurs Boost pour éviter les débordements de tampons idiots et les bogues de type non sûrs
John Dibling

7
@Maxim, pendant que vous soulevez un point valable, je prendrai la sécurité en sachant que mes tampons ne vont pas déborder et exploser mon application en morceaux. Je ne regarderais ces fonctions que si les formateurs de flux / boost étaient à l'origine de goulots d'étranglement notables. :)
Moo-Juice

1
@Maxim: Le fait est qu'il n'y a pas besoin. Mon code n'est pas un goulot d'étranglement. 5 m / s est le nombre de messages que l'échange envoie, pas le nombre que nous sommes capables de traiter. Alors pourquoi optimiser prématurément?
John Dibling

Réponses:


238

En C, un "flux" est une abstraction; du point de vue du programme, il s'agit simplement d'un producteur (flux d'entrée) ou d'un consommateur (flux de sortie) d'octets. Il peut correspondre à un fichier sur disque, à un canal, à votre terminal ou à un autre périphérique tel qu'une imprimante ou un terminal. Le FILEtype contient des informations sur le flux. Normalement, vous ne jouez pas FILEdirectement avec le contenu d' un objet, vous lui passez simplement un pointeur vers les différentes routines d'E / S.

Il existe trois flux standard: stdinun pointeur vers le flux d'entrée standard, stdoutun pointeur vers le flux de sortie standard et stderrun pointeur vers le flux de sortie d'erreur standard. Dans une session interactive, les trois se réfèrent généralement à votre console, bien que vous puissiez les rediriger pour pointer vers d'autres fichiers ou appareils:

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

Dans cet exemple, stdinpointe maintenant vers inputfile.dat, stdoutpointe vers output.txtet stderrpointe vers errors.txt.

fprintf écrit du texte formaté dans le flux de sortie que vous spécifiez.

printféquivaut à écrire fprintf(stdout, ...)et écrit du texte formaté là où le flux de sortie standard pointe actuellement.

sprintfécrit du texte formaté dans un tableau de char, par opposition à un flux.


4
"c'est simplement un producteur (flux d'entrée) ou un consommateur (flux de sortie) d'octets." Est-ce à l'envers? Un producteur ne créerait-il pas (sortie) quelque chose? Demander parce que je ne sais vraiment pas.
Dave Voyles

6
@DaveVoyles: Ce sont du point de vue de votre programme. Un flux d'entrée produit des octets que votre programme peut lire; un flux de sortie consomme les octets produits à partir de votre programme.
John Bode

153

printfsorties vers le flux de sortie standard ( stdout)

fprintfva à un descripteur de fichier ( FILE*)

sprintfva à un tampon que vous avez alloué. ( char*)


40

printf ("format", args) est utilisé pour imprimer les données sur la sortie standard qui est souvent un écran d'ordinateur.

sprintf (char *, "format", args) est comme printf. Au lieu d'afficher la chaîne formatée sur la sortie standard, c'est-à-dire un moniteur, il stocke les données formatées dans une chaîne pointée par le pointeur char (le tout premier paramètre). L'emplacement de la chaîne est la seule différence entre la syntaxe printf et sprint.

fprintf (FILE * fp, "format", args) est à nouveau comme printf. Ici, au lieu d'afficher les données sur le moniteur ou de les enregistrer dans une chaîne, les données formatées sont enregistrées dans un fichier pointé par le pointeur de fichier qui est utilisé comme premier paramètre de fprintf. Le pointeur de fichier est le seul ajout à la syntaxe de printf.

Si le fichier stdout est utilisé comme premier paramètre dans fprintf, son fonctionnement est alors considéré comme équivalent à celui de printf.


24

printf(...)est équivalent à fprintf(stdout,...).

fprintf est utilisé pour sortir en streaming.

sprintf(buffer,...) est utilisé pour formater une chaîne dans un tampon.

Notez qu'il y a aussi vsprintf, vfprintfetvprintf


Les vsaveurs ne sont pas standard je crois
John Dibling

8
Les vsaveurs sont très certainement dans la norme C.
Fred Foo

@larsmans: ah, ok. Merci pour la correction. Cette question a été à un moment donné marquée [c ++]
John Dibling

2

Vous pouvez également faire des choses très utiles avec la fonction 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 utile en effet, mais sachez qu'il vsnprintfs'agit d'une fonction non standard. La plupart des implémentations que j'ai vues implémentent ceci ou quelque chose comme ça, mais c'est spécifique à l'implémentation.
John Dibling

1
@larsmans mentionne ci-dessus que c'est en fait une partie de la norme C, donc je reprends cela
John Dibling

2
Qu'est-ce que cela a à voir avec C?
2011

2

printf

  1. printf est utilisé pour effectuer la sortie sur l'écran.
  2. syntaxe = printf("control string ", argument );
  3. Il n'est pas associé à l'entrée / sortie de fichier

fprintf

  1. Le fprintf utilisé pour effectuer une opération d'écriture dans le fichier pointé par le descripteur FILE.
  2. La syntaxe est fprintf (filename, "control string ", argument );
  3. Il est associé à l'entrée / sortie du fichier

Si cela est cité ailleurs, il est préférable de citer la source avec un lien, mais conservez certainement le texte que vous avez cité ici.
SuperBiasMan

0

fprintfCeci est lié aux flux où, comme printfune déclaration similaire fprintfmais non liée aux flux, c'est-à- fprintfdire liée au fichier


0

sprintf: écrit des données formatées dans une chaîne de caractères en mémoire au lieu de stdout

La syntaxe de sprintf est:

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

Ici,

La chaîne fait référence au pointeur vers un tampon en mémoire où les données doivent être écrites.

Le format fait référence au pointeur sur une chaîne de caractères définissant le format.

Chaque élément est une variable ou une expression spécifiant les données à écrire.

La valeur renvoyée par sprintf est supérieure ou égale à zéro si l'opération réussit ou en d'autres termes le nombre de caractères écrits, sans compter le caractère nul de fin est renvoyé et renvoie une valeur inférieure à zéro en cas d'erreur.

printf: imprime vers la sortie standard

La syntaxe de printf est:

printf format [argument]…

La seule différence entre sprintf () et printf () est que sprintf () écrit des données dans un tableau de caractères, tandis que printf () écrit des données sur stdout, le périphérique de sortie standard.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.