Que signifie le rinçage du tampon?

95

J'apprends le C ++ et j'ai trouvé quelque chose que je ne comprends pas:

Les tampons de sortie peuvent être explicitement vidés pour forcer l'écriture du tampon. Par défaut, la lecture des cinvidages cout; coutest également vidé lorsque le programme se termine normalement.

Donc vider le tampon (par exemple un tampon de sortie): est-ce que cela efface le tampon en supprimant tout ce qu'il contient ou efface-t-il le tampon en sortant tout ce qu'il contient? Ou est-ce que rincer le tampon signifie quelque chose de complètement différent?

Mohamed Ahmed Nabil
la source

Réponses:

122

Pensez à écrire dans un fichier. C'est une opération coûteuse. Si dans votre code vous écrivez un octet à la fois, alors chaque écriture d'un octet sera très coûteuse. Ainsi, un moyen courant d'améliorer les performances consiste à stocker les données que vous écrivez dans une mémoire tampon temporaire. Ce n'est que lorsqu'il y a beaucoup de données que le tampon est écrit dans le fichier. En reportant les écritures et en écrivant un gros bloc en une seule fois, les performances sont améliorées.

Dans cet esprit, vider le tampon est le fait de transférer les données du tampon vers le fichier.

Cela efface-t-il la mémoire tampon en supprimant tout ce qu'il contient ou efface-t-elle la mémoire tampon en sortant tout ce qu'elle contient?

Le dernier.

David Heffernan
la source
1
Merci. encore une chose. Lecture de cin flushes cout. Cette "lecture cin" signifie-t-elle lorsque l'utilisateur entre quelque chose ou lorsque l'utilisateur est invité à entrer quelque chose?
Mohamed Ahmed Nabil
4
La lecture cin se produit lorsque vous utilisez l'opérateur de flux pour lire à partir de cin. En règle générale, vous souhaitez vider cout lorsque vous lisez, car sinon l'entrée peut apparaître avant l'invite.
David Heffernan
1
@DavidHeffernan Autant que je sache, vous n'avez jamais besoin de vider cout avant cin, car cin et cout sont liés (Stroustrup, The C ++ Programming Language, [io.tie]).
sturmer
24

Vous avez cité la réponse:

Les tampons de sortie peuvent être explicitement vidés pour forcer l'écriture du tampon.

Autrement dit, vous devrez peut-être "vider" la sortie pour qu'elle soit écrite dans le flux sous-jacent (qui peut être un fichier ou, dans les exemples répertoriés, un terminal).

Généralement, stdout / cout est mis en tampon en ligne: la sortie n'est pas envoyée au système d'exploitation jusqu'à ce que vous écriviez une nouvelle ligne ou vidiez explicitement le tampon. L'avantage est que quelque chose comme std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlprovoque une seule écriture dans le "fichier" sous-jacent au lieu de six, ce qui est bien meilleur pour les performances. L'inconvénient est qu'un code comme:

for (int i = 0; i < 5; i++) {
    std::cout << ".";
    sleep(1); // or something similar
}

std::cout << "\n";

sortira .....immédiatement (pour une sleepimplémentation exacte , voir cette question ). Dans de tels cas, vous en voudrez un supplémentaire << std::flushpour vous assurer que la sortie est affichée.

Lecture des cinvidages coutpour ne pas avoir besoin d'un vidage explicite pour ce faire:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;
tc.
la source
Faire ceci pour (int i = 0; i <5; i ++) {std :: cout << "."; sommeil (1); } std :: cout << std :: endl; n'imprime pas ..... à la fois. Il les imprime avec 1 milliseconde entre les deux. Vous le remarquerez davantage lorsque vous utiliserez le sommeil (1000)
Mohamed Ahmed Nabil
@MohamedAhmedNabil Vous semblez confondre sleep()(POSIX) avec Sleep()(Windows)
tc.
1
Ancienne réponse, mais seul le commentaire porte moins sur le contenu que sur l'exemple. Vous êtes qualifié coutavec un espace de noms (c'est-à-dire std::cout) mais ne l' avez pas fait pour le endl, qui devrait également exiger cette qualification.
vol7ron
1
J'aime votre exemple. Mais je pensais qu'endl vidait le tampon, mais dans votre exemple, \ n vidait le tampon. Je suis confus.
Naz
1
@Naz \ n ne vide pas le tampon; le tampon n'est vidé qu'à la fin du programme dans son exemple (le tampon est toujours automatiquement vidé à la fin des programmes C ++). \ n a probablement été utilisé uniquement pour le formatage. De plus, vous avez raison de dire que std :: endl vide le tampon (tout comme std :: flush, mais cela va de soi).
liamnickell
4

Effacez le tampon en sortant tout.

Alex Chamberlain
la source