2010-09-16 6 views
16

Abschnitt 7.9.13/7 von c99 heißt es:Ist die Standardausgabe standardmäßig gepuffert, ungepuffert oder unbestimmt?

Bei Programmstart, sind drei Textströme vordefiniert und kann nicht müssen explizit geöffnet werden - die Standardeingabe (zum Lesen von herkömmlicher Eingabe), Standardausgabe (zum Schreiben von herkömmlichem Ausgang) und Standardfehler (zum Schreiben der Diagnoseausgabe).

Wie ursprünglich geöffnet, ist der Standardfehlerstrom nicht vollständig gepuffert; Standard-Input- und Standard-Output-Streams werden genau dann gepuffert, wenn der Stream so bestimmt werden kann, dass er sich nicht auf ein interaktives Gerät bezieht.

Das macht also Sinn. Wenn Sie Ihre Standardausgabe in eine Datei übertragen, möchten Sie, dass die Effizienz vollständig gepuffert ist.

Aber ich kann auf keine Erwähnung in der Norm festzustellen, ob der Ausgang Zeile gepuffert oder ungepuffert, wenn Sie nicht bestimmen das Gerät ist nicht interaktiv (dh normale Ausgabe an einen Terminal).

Der Grund frage ich einen Kommentar zu meine Antwort war here, daß ich eine fflush(stdout); zwischen den beiden Aussagen einfügen:

printf ("Enter number> "); 
// fflush (stdout); needed ? 
if (fgets (buff, sizeof(buff), stdin) == NULL) { ... } 

, weil ich nicht die printf mit einem Newline endet. Kann das jemand klären?

Antwort

26

Der C99-Standard spezifiziert nicht, ob die drei Standard-Datenströme ungepuffert oder zwischengespeichert sind: Es hängt von der Implementierung ab. Alle UNIX-Implementierungen, die ich kenne, haben eine Zeile gepuffert stdin. Unter Linux stdout in Zeile gepuffert und stderr ungepuffert.

Soweit ich weiß, auferlegt POSIX keine zusätzlichen Einschränkungen. POSIX des fflush Seite nicht beachten im Abschnitt BEISPIELE:

[...] Die Fflush() Funktion verwendet wird, da die Standardausgabe in der Regel gepuffert wird und die Aufforderung nicht sofort auf der Ausgangsklemme oder gedruckt werden.

Also die Bemerkung, die Sie fflush(stdout); hinzufügen, ist korrekt.

setbuf(stdout, NULL); 
/* or */ 
setvbuf(stdout, NULL, _IONBF, 0); 

Aber wie R. merkt man kann dies nur tun, einmal, und es müssen, bevor Sie auf andere operantion zu stdout oder führen Sie schreiben sein:


Eine Alternative könnte stdout ungepufferte machen sein es. (C99 7.19.5.5 2)


Ich habe gerade gelesen eine recent thread auf comp.lang.c über die gleiche Sache.Eine der Bemerkungen:

Unix Konvention ist, dass stdin und stdout linien gepuffert werden, wenn sie mit einem Anschluss verbunden ist, und vollständig gepufferte (auch bekannt als Block-gepuffert) andernfalls. stderr ist immer ungepuffert.

+0

Sie können "stdout" nicht "vorübergehend" ungepuffert machen. 'setbuf' und' setvbuf' haben undefiniertes Verhalten, es sei denn, sie sind die erste Operation, die nach dem Öffnen der Datei ausgeführt wird. –

+0

@R ..: Danke, du hast Recht. Ich habe das zur Antwort hinzugefügt. – schot

+0

Gibt es beim Zeilenpufferung ein hohes Wasserzeichen, wo, wenn die Linie zu lang wird, wird es gespült? – CMCDragonkai

Verwandte Themen