Was bedeutet das Spülen des Puffers?

95

Ich lerne C ++ und habe etwas gefunden, das ich nicht verstehen kann:

Ausgabepuffer können explizit geleert werden, um das Schreiben des Puffers zu erzwingen. Standardmäßig wird das Lesen von cinFlushes angezeigt cout. coutwird auch geleert, wenn das Programm normal endet.

Leeren Sie also den Puffer (zum Beispiel einen Ausgabepuffer): Löscht dies den Puffer, indem Sie alles darin löschen, oder löscht es den Puffer, indem Sie alles darin ausgeben? Oder bedeutet das Spülen des Puffers etwas völlig anderes?

Mohamed Ahmed Nabil
quelle

Antworten:

122

Schreiben Sie in eine Datei. Dies ist eine teure Operation. Wenn Sie in Ihrem Code jeweils ein Byte schreiben, ist jedes Schreiben eines Bytes sehr kostspielig. Eine übliche Methode zur Verbesserung der Leistung besteht darin, die Daten, die Sie schreiben, in einem temporären Puffer zu speichern. Nur wenn viele Daten vorhanden sind, wird der Puffer in die Datei geschrieben. Durch Verschieben der Schreibvorgänge und Schreiben eines großen Blocks auf einmal wird die Leistung verbessert.

In diesem Sinne bedeutet das Leeren des Puffers das Übertragen der Daten vom Puffer in die Datei.

Löscht dies den Puffer, indem alles darin gelöscht wird, oder löscht es den Puffer, indem alles darin ausgegeben wird?

Letzteres.

David Heffernan
quelle
1
Vielen Dank. eine Sache noch. Das Lesen von Cin spült Cout. Bedeutet dieses "Lese-Cin", wenn der Benutzer etwas eingibt oder wenn der Benutzer aufgefordert wird, etwas einzugeben?
Mohamed Ahmed Nabil
4
Das Lesen von cin erfolgt, wenn Sie den Stream-Operator zum Lesen von cin verwenden. Normalerweise möchten Sie Cout beim Lesen löschen, da sonst die Eingabe möglicherweise vor der Eingabeaufforderung angezeigt wird.
David Heffernan
1
@DavidHeffernan Soweit ich weiß, müssen Sie cout nie vor cin spülen, da cin und cout miteinander verbunden sind (Stroustrup, The C ++ Programming Language, [io.tie]).
Sturmer
24

Sie haben die Antwort zitiert:

Ausgabepuffer können explizit geleert werden, um das Schreiben des Puffers zu erzwingen.

Das heißt, Sie müssen möglicherweise die Ausgabe "leeren", damit sie in den zugrunde liegenden Stream (der eine Datei oder in den aufgeführten Beispielen ein Terminal sein kann) geschrieben wird.

Im Allgemeinen ist stdout / cout zeilengepuffert: Die Ausgabe wird erst an das Betriebssystem gesendet, wenn Sie eine neue Zeile schreiben oder den Puffer explizit leeren. Der Vorteil ist, dass so etwas std::cout << "Mouse moved (" << p.x << ", " << p.y << ")" << endlnur einen Schreibvorgang in die zugrunde liegende "Datei" anstelle von sechs verursacht, was für die Leistung viel besser ist. Der Nachteil ist, dass ein Code wie:

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

std::cout << "\n";

wird .....sofort ausgegeben (genaue sleepImplementierung siehe diese Frage ). In solchen Fällen benötigen Sie eine zusätzliche, << std::flushum sicherzustellen, dass die Ausgabe angezeigt wird.

Lesen Sie cinFlushes, coutdamit Sie dazu keine explizite Flush benötigen:

std::string colour;
std::cout << "Enter your favourite colour: ";
std::cin >> colour;
tc.
quelle
Dies tun für (int i = 0; i <5; i ++) {std :: cout << "."; Schlaf (1); } std :: cout << std :: endl; druckt nicht ..... sofort. Es druckt sie mit 1 Millisekunde dazwischen. Sie werden es mehr bemerken, wenn Sie Schlaf verwenden (1000)
Mohamed Ahmed Nabil
@MohamedAhmedNabil Sie scheinen sleep()(POSIX) mit Sleep()(Windows)
tc
1
Alte Antwort, aber nur Kommentar bezieht sich weniger auf den Inhalt als vielmehr auf das Beispiel. Sie qualifizieren sich coutmit einem Namespace (dh std::cout), haben dies jedoch nicht für den getan, für den endlauch diese Qualifikation erforderlich sein sollte.
Vol7ron
1
Ich mag dein Beispiel. Aber ich dachte, endl leert den Puffer, aber in Ihrem Beispiel spült \ n den Puffer. Ich bin verwirrt.
Naz
1
@Naz \ n leert den Puffer nicht; Der Puffer wird in seinem Beispiel nur am Ende des Programms geleert (der Puffer wird am Ende von C ++ - Programmen immer automatisch geleert). \ n wurde wahrscheinlich nur zum Formatieren verwendet. Sie haben auch Recht, dass std :: endl den Puffer leert (std :: flush auch, aber das ist selbsterklärend).
Liamnickell
4

Löschen Sie den Puffer, indem Sie alles ausgeben.

Alex Chamberlain
quelle