2010-01-23 12 views
14

Stdout ist Line-gepuffert, wenn an ein Terminal angeschlossen ist, aber ich erinnere mich irgendwo lesen, dass Lesen (zumindest von Stdin) automatisch stdout flush. Alle C-Implementierungen, die ich verwendet habe, haben dies getan, aber ich kann es jetzt im Standard nicht finden.Liest von stdin flush stdout?

Es macht Sinn, dass es so funktioniert, sonst Code wie folgt:

printf("Type some input: "); 
fgets(line, sizeof line, stdin); 

müsste eine zusätzliche fflush(stdout);

So garantiert stdout hier gespült werden?

EDIT:

Wie mehr Antworten gesagt haben, scheint es keine Garantie in der Norm zu sein, dass die Ausgabe in meinem Beispiel nach stdout wird vor dem Lesen von stdin erscheinen, aber auf der anderen Seite wird diese Absicht in (meine freien Entwurf Kopie) die Norm angegeben:

die Eingangs- und Ausgangsdynamik interaktiver Geräte Platz in 7.19.3 wie angegeben nehmen soll. Die Absicht von diese Anforderungen ist, dass ungepufferte oder Linie gepufferte Ausgabe so bald wie möglich erscheinen, um sicherzustellen, dass die Aufforderung Nachrichten tatsächlich vor einem Programm angezeigt werden, das auf Eingabe wartet.

(ISO/IEC 9899: TC2 Ausschussentwurf - 6. Mai 2005, Seite 14).

Es scheint also, dass es keine Garantie gibt, aber es wird wahrscheinlich in den meisten Implementierungen sowieso funktionieren. (Berühmte letzte Worte ...)

+1

Der Querverweis auf 7.19.3 (7.21.3 in C11) ist ebenfalls nützlich, da hier erwähnt wird, welche Eingabeoperationen Spülen verursachen sollen. Diese werden unter https://stackoverflow.com/a/39536803/8586227 erläutert. –

Antwort

4

Nein, tut es nicht.

+0

Aber im Allgemeinen, was wir sehen, ist, dass stdout vor fgets Linie gespült wird. Also, warum wird es hier geleert? –

+0

Es scheint, dass eine C-Implementierung _allowed_ vom Standard ist, um die Eingabeaufforderung nicht vor den Fgets zu drucken, aber die "Intension" ist, dass es sollte, und ich denke, dass die meisten (alle?) Implementierungen tun. –

+0

Das Folgen dieser Absicht würde alle Eingabe viel langsamer und für zweifelhaften Nutzen machen. –

4

Nein. Sie müssen fflush (stdout); Viele Implementierungen werden bei jeder neuen Zeile gelöscht, wenn sie die Ausgabe an ein Terminal senden.

+0

AFIAK 'stdout' wird standardmäßig standardmäßig als leitungsgepuffert oder ungepuffert verwendet. – ybungalobill

5

Ihre Frage zu beantworten, Sie die Eingabeaufforderung angezeigt machen tun, um die zusätzlichen fflush(stdout); nach Ihrem printf() Anruf sicher müssen, bevor Ihr Programm versucht Eingang zu lesen. Lesen von stdin nicht fflush(stdout); für Sie.

4

Nr. Stdin/stdout sind gepuffert. Sie müssen fflush(stdout) explizit angeben, damit die gepufferten Daten im Speicher des Videospeichers/Unix-Terminals auf ein Anzeigegerät wie ein Terminal übertragen werden. Die Pufferung der Daten kann durch Aufruf von setvbuf eingestellt werden.

Bearbeiten: Dank Jonathan, um die Frage zu beantworten, liest von stdin nicht stdout flush. Ich bin vielleicht hier eine Tangente gegangen, indem ich den Code angegeben habe, der zeigt, wie man setvbuf benutzt.

 
    #include 

    int main(void) 
    { 
    FILE *input, *output; 
    char bufr[512]; 

    input = fopen("file.in", "r+b"); 
    output = fopen("file.out", "w"); 

    /* set up input stream for minimal disk access, 
     using our own character buffer */ 
    if (setvbuf(input, bufr, _IOFBF, 512) != 0) 
     printf("failed to set up buffer for input file\n"); 
    else 
     printf("buffer set up for input file\n"); 

    /* set up output stream for line buffering using space that 
     will be obtained through an indirect call to malloc */ 
    if (setvbuf(output, NULL, _IOLBF, 132) != 0) 
     printf("failed to set up buffer for output file\n"); 
    else 
     printf("buffer set up for output file\n"); 

    /* perform file I/O here */ 

    /* close files */ 
    fclose(input); 
    fclose(output); 
    return 0; 
    } 

hoffe, das hilft, Mit freundlichen Grüßen, Tom.

+0

Wie verhält sich Ihr Code zum Verhalten von stdin und stdout? –

+0

@ Jonathan: Es ist ein Beispiel, wie der Puffer für die Eingabe festgelegt wird, indem Setvbuf 512 oder eine beliebige Zahl für die Angelegenheit, vorzugsweise auf einer Wortgrenze verwendet. Das war ein Beispiel aus der Hilfedatei des Borland C-Compilers, das die Verwendung von setvbuf zeigt. – t0mm13b

+0

Der Code ist in Ordnung als Antwort auf eine andere Frage - es befasst sich nicht mit der Frage, die lautet "liest von Standard-Flush-Stdout". Ich werde dich nicht für eine tangentiale Antwort bestrafen - aber ich betrachte deine Antwort als tangential. –

2

Nein, das gehört nicht zum Standard.Es ist sicherlich möglich, dass Sie eine Bibliotheksimplementierung verwendet haben, bei der das von Ihnen beschriebene Verhalten aufgetreten ist, aber das ist eine nicht standardmäßige Erweiterung, auf die Sie sich nicht verlassen sollten.

1

Nein. Achten Sie auf Interprozess-Deadlocks beim Umgang mit Std-Streams, wenn Sie entweder auf stdin lesen oder auf stdout-Blöcke schreiben.