2010-09-16 5 views
16

Section 7.9.13/7 de c99 stipule que:La ligne stdout est-elle mise en mémoire tampon, non tamponnée ou indéterminée par défaut?

Au démarrage du programme, trois flux de texte sont prédéfinis et ne doivent pas être ouverts explicitement - l'entrée standard (pour la lecture des données), la sortie standard (pour l'écriture sortie conventionnelle) et erreur standard (pour l'écriture de la sortie de diagnostic).

A l'ouverture initiale, le flux d'erreur standard n'est pas entièrement mis en mémoire tampon; les flux d'entrée standard et de sortie standard sont entièrement tamponnés si et seulement si le flux peut être déterminé comme ne faisant pas référence à un périphérique interactif.

Cela a du sens. Si vous placez votre sortie standard dans un fichier, vous voulez qu'elle soit entièrement mise en mémoire tampon pour plus d'efficacité.

Mais je ne trouve aucune mention dans la norme quant à savoir si la sortie est bufferisée ou non lorsque ne peut pas déterminer que le périphérique est non interactif (c'est-à-dire, sortie normale vers un terminal).

La raison pour laquelle je demande est un commentaire à ma réponse here que j'insérer une fflush(stdout); entre les deux déclarations:

printf ("Enter number> "); 
// fflush (stdout); needed ? 
if (fgets (buff, sizeof(buff), stdin) == NULL) { ... } 

parce que je ne met fin à la printf avec un saut de ligne. Quelqu'un peut-il éclaircir cela?

Répondre

26

La norme C99 ne spécifie pas si les trois flux standard sont sans tampon ou ligne bufférisée: Cela dépend de l'implémentation. Toutes les implémentations UNIX que je connais ont une ligne mise en mémoire tampon stdin. Sous Linux, stdout en ligne mis en mémoire tampon et stderr non tamponné. Pour autant que je sache, POSIX n'impose pas de restrictions supplémentaires. Page fflush POSIX ne note dans la section Exemples:

[...] Le fflush() fonction est utilisée parce que la sortie standard est généralement en mémoire tampon et l'invite ne peut pas être immédiatement imprimé sur la sortie ou la borne. La remarque que vous ajoutez fflush(stdout); est correcte.


Une alternative pourrait consister à stdout unbuffered:

setbuf(stdout, NULL); 
/* or */ 
setvbuf(stdout, NULL, _IONBF, 0); 

Mais comme R. note vous ne pouvez faire qu'une seule fois, et il doit être avant de vous écrire à stdout ou d'effectuer tout autre operantion sur il. (C99 7.19.5.5 2)


Je viens de lire un recent thread sur comp.lang.c de la même chose.L'une des remarques:

convention Unix est que stdin et stdout sont ligne en mémoire tampon lors associé à un terminal, et FB-DIMM (aka bloc-tampon) autrement. stderr est toujours sans tampon.

+0

Vous ne pouvez pas "temporairement" rendre "stdout" non tamponné. 'setbuf' et' setvbuf' ont un comportement indéfini sauf s'il s'agit de la première opération effectuée sur le fichier après son ouverture. –

+0

@R ..: Merci, vous avez raison. J'ai ajouté ceci à la réponse. – schot

+0

Dans le cas de la mise en mémoire tampon, y at-il un filigrane haut où, si la ligne devient trop longue, elle sera rincée? – CMCDragonkai

Questions connexes