Pourquoi ne printf pas rincer après l'appel, à moins d'un retour à la ligne est dans la chaîne de format?
Pourquoi ne printf
pas rincer après l'appel, à moins d'un retour à la ligne est dans la chaîne de format? Est-ce un comportement POSIX? Comment pourrais-je avoir printf
immédiatement rincer à chaque fois?
- avez-vous cherché à savoir si ce qui se passe avec n'importe quel fichier ou uniquement avec les terminaux? que serait son pour être un savant terminal dispose pas de sortie inachevés ligne à partir d'un programme en tâche de fond, même si j'attends qu'il ne s'applique pas à l'avant-plan du programme.
- Sous Cygwin bash je le vois même les débordements, même si un retour à la ligne est dans la chaîne de format. Ce problème est nouveau pour Windows 7; de la même source, le code a bien fonctionné sur Windows XP. MS cmd.exe bouffées de chaleur comme prévu. Le correctif
setvbuf(stdout, (char*)NULL, _IONBF, 0)
contourne le problème, mais ne devrait certainement pas été nécessaire. Je suis l'aide de MSVC++ 2008 Express. ~~~ - Pour préciser le titre de la question:
printf(..)
ne pas faire de rinçage lui-même, c'est la mise en mémoire tampon destdout
qui peuvent vider lors de voir un retour à la ligne (si c'est la ligne tampon). Il allait réagir de la même façon àputchar('\n');
, doncprintf(..)
n'est pas spécial à cet égard. Ceci est en contraste aveccout << endl;
, le documentation de qui en évidence mentionne le rinçage. Le documentation de printf ne parle pas de rinçage à tous. - l'écriture (/rinçage) est potentiellement une opération coûteuse, c'est probablement mis en mémoire tampon pour des raisons de performances.
Vous devez vous connecter pour publier un commentaire.
La
stdout
flux est de la ligne de tampon par défaut, donc n'affichera que ce qui est dans la mémoire tampon après avoir atteint un saut de ligne (ou quand c'est dit). Vous avez un peu d'options pour imprimer immédiatement:Impression de
stderr
au lieu d'utiliserfprintf
(stderr
est sans tampon par défaut):Flush stdout chaque fois que vous en avez besoin à l'aide de
fflush
:Modifier: De Andy Ross commentaire ci-dessous, vous pouvez également désactiver la mise en mémoire tampon sur la sortie standard en utilisant
setbuf
:setbuf(stdout, NULL);
setlinebuf()
sur un ruisseau qui n'est pas destiné à un terminal est rinçage à la fin de chaque ligne.exit
fonction de la bibliothèque standard de vidage de la mémoire tampon.fflush(stdout);
si je suis en utilisantfprintf()
pour imprimer sur un fichier?Non, il n'est pas POSIX comportement, c'est de l'ISO comportement (bon, c' est POSIX comportement, mais seulement dans la mesure où ils sont conformes à la norme ISO).
Sortie Standard est la ligne de tampon si elle peut être détectée à se référer à un dispositif interactif, sinon il est entièrement mis en mémoire tampon. Il y a des situations où
printf
ne pas rincer, même s'il fait un retour à la ligne pour envoyer, tels que:Cela a un sens pour l'efficacité car, si vous êtes en interaction avec un utilisateur, ils veulent probablement pour voir chaque ligne. Si vous êtes à envoyer la sortie vers un fichier, il est plus que probable qu'il n'y a pas un utilisateur à l'autre bout (mais pas impossible, ils pourraient être de résidus de la file). Maintenant, vous pourrait soutiennent que l'utilisateur veut les voir chaque personnage, mais il y a deux problèmes avec ça.
La première est qu'il n'est pas très efficace. La deuxième est que le C ANSI mandat avait pour principal objet de codifier existant comportement, plutôt que d'inventer nouveau comportement, et ceux de la conception des décisions ont été prises bien avant ANSI a commencé le processus. Même ISO de nos jours de marches très attentivement lors de la modification des règles existantes dans les normes.
Façon de traiter avec cela, si vous
fflush (stdout)
après chaque sortie que vous souhaitez voir immédiatement, qui permettra de résoudre le problème.Alternativement, vous pouvez utiliser
setvbuf
avant d'opérer surstdout
, pour le mettre en mémoire sans tampon et vous ne devez pas vous inquiéter au sujet de l'ajout de tous cesfflush
lignes de code:Il suffit de garder à l'esprit que peut affecter les performances tout à fait un peu si vous sont envoyer la sortie vers un fichier. Aussi garder à l'esprit que le soutien à cette mise en œuvre est définie, non garantie par la norme.
ISO C99 section
7.19.3/3
est le bit:myprog >/tmp/tmpfile
, entièrement mis en mémoire tampon plutôt que de la ligne de mise en mémoire tampon. De mémoire, la détermination à savoir si votre sortie standard est interactif est laissé à la mise en œuvre.C'est probablement comme ça à cause de l'efficacité et parce que si vous avez plusieurs programmes d'écriture à un seul ATS, de cette façon, vous n'obtenez pas de caractères sur une ligne de l'entrelacé. Donc, si le programme A et B sont de sortie, vous aurez généralement obtenir:
Cela pue, mais c'est mieux que
Noter qu'il n'est même pas garanti de chasse sur un retour à la ligne, de sorte que vous devriez rincer explicitement si le rinçage est important pour vous.
À rincer immédiatement appel
fflush(stdout)
oufflush(NULL)
(NULL
signifie vider).fflush(NULL);
est généralement une très mauvaise idée. Il va tuer les performances si vous avez beaucoup de fichiers à ouvrir, surtout dans un environnement multi-threads où vous combattrez avec tout pour les serrures.Remarque: Microsoft runtime des bibliothèques ne pas la ligne de support de mise en mémoire tampon, de sorte
printf("will print immediatelly to terminal")
:http://msdn.microsoft.com/en-us/library/86cebhfs.aspx
printf
va immédiatement à la borne dans le cas "normal", c'est le fait queprintf
etfprintf
obtenir plus grossièrement tamponnée même dans les cas où leur production est d'une utilisation immédiate. À moins que MS a fixé les choses, qui rend impossible pour un programme de capture stderr et stdout d'une autre, et d'identifier dans quel ordre les choses ont été envoyés à chacun.stdout est mis en mémoire tampon, il en sera de sortie seulement après un retour à la ligne est imprimé.
Pour obtenir de sortie immédiate, soit:
fflush(stdout)
.stderr
(cette réponse mentionne plus tard),fflush(stdout)
,fflush(NULL)
.par défaut, la sortie standard est la ligne de tampon, stderr n'est tamponnée et le fichier est totalement mis en mémoire tampon.
Vous pouvez fprintf à stderr, qui est sans tampon, à la place. Ou vous pouvez flush stdout quand vous le souhaitez. Ou vous pouvez régler la sortie standard (stdout) de barrettes de mémoire.
Utilisation
setbuf(stdout, NULL);
pour désactiver la mise en mémoire tampon.