2017-11-05 2 views
4

Ich lerne über iostream Objekte und spült den Puffer. Ich weiß, wann Ausgabepuffer garantiert geleert werden und wie der Puffer explizit geleert wird. Jedoch habe ich nie einen Fall gesehen, in dem der Ausgabepuffer nicht gespült wird. Es scheint mir, dass der Ausgabepuffer am Ende jeder Anweisung geleert wird, auch wenn ich keine Manipulatoren wie endl, flush und ends verwende.Fall (e), in dem der Ausgabepuffer nicht spült?

So ist es ein einfaches Beispiel (e), in dem der Ausgangspuffer nicht (oder zumindest könnte oft nicht) gespült werden? Ich habe das Gefühl, dass ich einen solchen Fall sehen muss, um Ausgabepuffer wirklich zu verstehen.

+1

Denken Sie daran, dass es zwei Ebene der Pufferung sind und beteiligt Spülung: Buffering innerhalb des Upstream-Objekts, das von der Standardeinstellung für cout gedreht, und Buffering des Stroms in dem O. – MikeMB

+0

@MikeMB 'cout' hat die Pufferung ausgeschaltet? Meinst du "unitbuff"? Wenn nicht, kann ich es einschalten? –

+0

['std :: ios :: sync_with_stdio (false)'] (http://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio) – MikeMB

Antwort

3

Hängt vom System ab.

Nehmen Sie das folgende Programm als Beispiel:

#include <iostream> 
#ifdef WIN32 
#include <windows.h> 
#define sleep(n) Sleep((n)*1000) 
#else 
#include <unistd.h> 
#endif 

using namespace std; 

int main() 
{ 
    cout << "This is line 1"; 
    sleep(4); 
    cout << endl; 
    cout << "This is line 2" << endl; 

    return 0; 
} 

Durch das Programm genauer ansehen, könnten Sie vermuten, dass das Programm This is line 1 drucken würde, gefolgt von 4 Sekunden Pause, dann This is line 2 Druck.

Und wenn Sie mit Visual Studio für die Ausführung unter Windows kompilieren, erhalten Sie genau dieses Verhalten.

Unter Linux und anderen Unix-Betriebssystemen jedoch, wird das Programm erscheint still für 4 Sekunden dauern, bis beide zusammen Linien ausdrucken. Die Ausgabe wird nicht zuverlässig gelöscht, bis ein neues Zeilenzeichen im Ausgabestream gefunden wird.

+0

Ah, also ist es systemabhängig. Deshalb habe ich solche Fälle nie gesehen, seit ich Visual Studio verwende. Vielen Dank! –

+1

"Die Ausgabe wird nicht zuverlässig geleert, bis ein neues Zeilenzeichen im Ausgabestream gefunden wird" ist * nicht * ganz * korrekt. Eine neue Zeile '\ n' verursacht * nicht * einen Flush, aber' std :: endl', weil sie einen Zeilenumbruch gefolgt von einem 'std :: flush' ausgibt. Was macht 'std :: endl 'in einigen Fällen ziemlich teuer und warum sollte man' \ n' bevorzugen, es sei denn, ein flush wird auch explizit benötigt/gewünscht - in diesem Fall ist 'std :: endl' das richtige Werkzeug . –

+2

@JesperJuhl: Sie müssen zwischen std :: cout und filestreams unterscheiden und das Iostream-Objekt und die Pufferung im OS/Konsolenfenster zwischenspeichern. Standardmäßig puffert std :: cout nichts, sondern sendet jede Eingabe direkt an das Betriebssystem (z. B. über 'write' auf linux) und normalerweise, die ihren eigenen Puffer löscht, wenn sie ein Newline-Zeichen (oder früher) empfängt. In diesem Modus gibt es fast keinen Unterschied zwischen der Verwendung von '\ n' und' std :: endl'. Wenn Sie die Pufferung innerhalb des Iostream-Objekts aktivieren (oder einen Filestream verwenden), sind Sie vollkommen korrekt – MikeMB