Quelqu'un peut-il expliquer en anglais simple les différences entre printf
, fprintf
et sprintf
avec des exemples ?
Dans quel courant se trouve-t-il ?
Je suis vraiment confus entre les trois en lisant "File Handling in C".
Quelqu'un peut-il expliquer en anglais simple les différences entre printf
, fprintf
et sprintf
avec des exemples ?
Dans quel courant se trouve-t-il ?
Je suis vraiment confus entre les trois en lisant "File Handling in C".
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 le disque, à un tube, à votre terminal ou à un autre périphérique tel qu'une imprimante ou un tty. Le site FILE
contient des informations sur le flux. Normalement, on ne s'embarrasse pas d'un type FILE
directement le contenu de l'objet, vous passez simplement un pointeur sur celui-ci aux différentes routines d'E/S.
Il existe trois flux standard : stdin
est un pointeur vers le flux d'entrée standard, stdout
est un pointeur vers le flux de sortie standard, et stderr
est un pointeur vers le flux de sortie de l'erreur standard. Dans une session interactive, les trois font généralement référence à votre console, bien que vous puissiez les rediriger pour pointer vers d'autres fichiers ou périphériques :
$ myprog < inputfile.dat > output.txt 2> errors.txt
Dans cet exemple, stdin
indique maintenant inputfile.dat
, stdout
Les points suivants output.txt
et stderr
Les points suivants errors.txt
.
fprintf
écrit du texte formaté dans le flux de sortie que vous spécifiez.
printf
est équivalent à écrire fprintf(stdout, ...)
et écrit le texte formaté à l'endroit où le flux de sortie standard pointe actuellement.
sprintf
écrit du texte formaté dans un tableau de char
par opposition à un flux.
"c'est simplement un producteur (flux d'entrée) ou un consommateur (flux de sortie) d'octets." Est-ce que c'est à l'envers ? Un producteur ne devrait-il pas créer (sortir) quelque chose ? Je pose la question parce que je ne sais vraiment pas.
@DaveVoyles : Ils 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 par votre programme.
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 que vsnprintf
est une fonction non standard. La plupart des implémentations que j'ai vues l'implémentent ou quelque chose comme ça, mais c'est spécifique à l'implémentation.
@larsmans mentionne ci-dessus que cela fait en fait partie du standard C, donc je retire ce que j'ai dit.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
4 votes
Expérimentez-les en écrivant quelques exemples de code. C'est une façon très simple de clairement comprendre la différence entre eux.
21 votes
Préférez snprintf() à sprintf() pour éviter les stupides débordements de tampon.
3 votes
Préférez les flux ou les formateurs Boost pour éviter les débordements de tampon et les bogues de non sécurité de type.
0 votes
Les flux et les formateurs de boost peuvent être trop lents.
7 votes
@Maxim, bien que vous souleviez un point valide, je prendrai la sécurité de savoir que mes tampons ne vont pas déborder et faire exploser mon application en morceaux. Je n'envisagerais ces fonctions que si les formateurs de flux/boost étaient à l'origine de goulots d'étranglement notables :)
0 votes
J'ai supprimé l'étiquette C, ce sont des fonctions C et bien que vous puissiez les appeler depuis le C++, il est préférable de ne pas le faire, de cette façon vous éviterez les programmeurs grincheux (en C++, utilisez les flux).
0 votes
@Maxim : Presque jamais. J'utilise des flux dans des serveurs financiers de production, traitant 5 millions de messages par seconde, toute la journée, tous les jours, et ils n'ont jamais été un problème pour moi.
0 votes
@Matthieu : Je pense que tu as laissé tomber la balise [c++]. Est-ce que c'était voulu ?
0 votes
@John : la sécurité de type des flux est un peu surfaite. Les compilateurs modernes vérifient les arguments par rapport à la chaîne de format, assurez-vous simplement de ne pas ignorer ces avertissements ou d'en faire une erreur difficile. Et à la fin de la journée, les streams appellent snprintf sous le capot, donc en n'utilisant pas les streams vous évitez des couches de code.
0 votes
@John : 5M/sec messages est 200ns/msg. Je parie que tu pourrais faire mieux que ça si tu laissais tomber IOStreams. lol
1 votes
@Maxim : Le fait est, qu'il n'y a pas besoin. Mon code n'est pas un goulot d'étranglement. 5m/sec est le nombre de messages que l'échange envoie, pas le nombre de messages que nous sommes capables de traiter. Alors pourquoi optimiser prématurément ?
0 votes
@John : Avec les données de marché et le trading à haute fréquence, l'objectif n'est souvent pas le débit, mais plutôt la latence.
0 votes
@Maxim : Je suis bien conscient de cela. Encore une fois, ce n'est pas un problème dans mon expérience.