2009-04-28 4 views
3

Selon this post std :: cout va automatiquement vider \n lorsqu'il est attaché à un dispositif interactif (par exemple une fenêtre de terminal). Dans le cas contraire (par exemple lorsqu'il est envoyé vers un fichier), il agira en mémoire tampon et ne videra que sur .flush() ou std::endl.Puis-je arrêter std :: cout flush sur " n"?

Existe-t-il un moyen de remplacer ce comportement dans Microsoft Visual C++ afin que je puisse sélectionner si je veux le mode entièrement mis en mémoire tampon ou ligne tamponnée?

+0

Peut-être que cela peut être utile, je doute que cela vous aide beaucoup avec votre problème si. http://nibuthomas.com/2009/02/12/writing-endl-like-functions-for-output-streams/ – Skurmedel

+0

Il semble qu'il y ait un débat quant à la légitimité de l'affirmation selon laquelle C++ incorpore la ligne C90 tamponnée vs distinction entièrement bufferisée pour std :: cout. Peu importe, existe-t-il un moyen de changer entre les modes de mise en mémoire tampon avec MSVC? – pauldoo

+0

Peut-être que vous pourriez écrire un programme de test et voir si la revendication est vraie? – Skurmedel

Répondre

1

Ce n'est pas un problème avec C++ (il n'y a aucune exigence de langue qui vide quelque chose) mais avec votre système d'exploitation et/ou votre logiciel de console. Si la console veut vider son tampon quand elle voit une nouvelle ligne, alors elle le peut, et je suppose que la plupart le font. Notez qu'il est important de différencier les tampons d'exécution C++ (qui peuvent être contrôlés dans une certaine mesure à partir de votre code C++) et les tampons de l'application console (sur laquelle elle n'a aucun contrôle). FYI, il y a un drapeau dans la bibliothèque iostream standard appelé unitbuf qui, s'il est défini, provoque le vidage des tampons après chaque opération de sortie. Il est défini, par exemple, pour le flux std :: cerr. Cela n'a cependant rien à voir avec le caractère '\ n', car vous pouvez sortir plusieurs '\ n' en une seule opération.

+0

De la page que j'ai liée à: "Si la sortie standard est ou peut être attachée à un périphérique interactif, elle est mise en mémoire tampon, sinon elle est entièrement mise en mémoire tampon.(C99 spécifie ceci dans la section 7.19.3 paragraphe 7, je crois que C90 dit la même chose, et C++ 98 incorpore C90 par référence.) "Croyez-vous que ce soit faux? – pauldoo

+2

Je n'ai pas accès à la norme C Cependant, le standard C++ n'incorpore pas le standard C, par référence ou autrement Le standard C++ fait référence à la norme C dans des cas spécifiques –

+0

@pauldoo: J'ai entendu cette affirmation au sujet de C++ incorporant C avant, mais pour autant que je sache, il ne fait référence qu'à des sections spécifiques – jalf

0

Une implémentation est libre de vider chaque fois qu'elle le juge approprié. Il varie d'un fournisseur à l'autre, qu'ils vident sur \n ou non.

Je peux voir quelque chose appelé ios_base& nounitbuf(ios_base& str); à partir de mon brouillon C++ 0x. Donner un coup de feu. C'est à peu près la seule chose que le C++ standard vous donne.

+0

nonunitbuf Il ne semble pas être dans la norme actuelle –

+0

Hm, je n'étais pas sûr si j'avais mentionné le projet – dirkgently

+0

Cependant, la recherche diligente indique qu'il y a un drapeau de flux "unitbuf" fixant ce sh Rincez le flux après chaque opération. Je mettrai à jour ma réponse pour refléter ceci. –

7

Contrairement à la réponse d'anon (28 avril 2009), ce comportement n'a rien à voir avec le système d'exploitation ou le «logiciel de console».

C flux de <iostream> ++ sont conçus pour être interopérable avec <stdio.h> flux de carbone. L'objectif est de permettre le mélange des utilisations de std::cout avec les utilisations de printf/puts. Pour ce faire, streambuf de std::cout est implémenté sur le flux stdout de C. Il s'agit en fait de stdout de C qui est mis en mémoire tampon lorsque la sortie standard est connectée à un périphérique de terminal. Vous pouvez appeler std::ios_base::sync_with_stdio(false) (avant que votre programme n'utilise l'un des flux d'E/S standard du C++) pour indiquer à la bibliothèque de flux C++ de communiquer directement avec les descripteurs de fichiers sous-jacents plutôt que sur la bibliothèque de flux C's. Ceci évite entièrement le flux stdout de C et accélère les flux d'E/S de C++ au prix que les deux bibliothèques ne se mélangent plus bien.

Une alternative consiste à définir inconditionnellement stdout pour entièrement mis en mémoire tampon en appelant std::setvbuf(stdout, nullptr, _IOFBF, BUFSIZ). Ensuite, même si std::cout écrit toujours à travers stdout, vous n'aurez pas stdout flush après chaque nouvelle ligne.

Questions connexes