stdout-Ausgabestrom in C leeren
-
Verwenden Sie die Funktion
fflush
, um denstdout
-Ausgabestrom in C zu leeren -
Demonstration des
fflush
-Verhaltens mit der Funktionprintf
in C
Dieser Artikel demonstriert mehrere Methoden, wie man den stdout
-Ausgabestrom in C leeren kann.
Verwenden Sie die Funktion fflush
, um den stdout
-Ausgabestrom in C zu leeren
Die C-Standardbibliothek bietet eine I/O
-Bibliothek, stdio
, die im Wesentlichen eine gepufferte Version der E/A-Operationen darstellt, die im Userspace durchgeführt werden, wodurch die Leistung für häufige Anwendungsfälle verbessert wird. Im Allgemeinen wird der Zugriff auf Dateien und die Durchführung von Operationen auf ihnen von den Diensten des Betriebssystems bereitgestellt; daher benötigt der Benutzer irgendwann einen Systemaufruf, um z. B. eine Datei zu öffnen. Ein häufiger Aufruf von Systemaufrufen macht das Programm langsamer, da es auf Datenstrukturen des Betriebssystemkerns zugreift und die Kontrolle hin und her transferiert. Aus diesem Grund gibt es Puffer, die von der C-Bibliothek für die Handhabung der Ein-/Ausgabeoperationen bei der Verwendung der stdio
-Funktionsaufrufe unterhalten werden.
Wenn der Benutzer das Schreiben in die Kernel-Puffer erzwingen will, muss er den angegebenen Stream, der von der Funktion fflush
bereitgestellt wird, flushen. Die Funktion fflush
nimmt als einziges Argument den Zeiger FILE
auf den angegebenen Stream entgegen. Beachten Sie, dass fflush
die Schreibfunktion für Ausgabestreams erzwingt, während bei Eingabestreams (mit durchsuchbaren Dateien) alle gepufferten Daten verworfen werden. Wenn das Argument NULL
ist, werden alle offenen Ausgabeströme geleert.
Beachten Sie jedoch, dass fflush
nicht sicherstellt, dass geschriebene Daten physisch gespeichert werden, da dazu die Kernel-Puffer geleert werden müssen (was mit dem Aufruf fsync
erreicht werden kann, siehe hier).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char *username;
size_t len;
int lnmax = 256;
username = malloc(lnmax);
if (username == NULL) perror("malloc");
printf("Username: ");
fflush(stdout);
if (fgets(username, lnmax, stdin) == NULL) exit(EXIT_FAILURE);
printf("Your username is set to - %s", username);
exit(EXIT_SUCCESS);
}
Ausgabe:
Username: tmp
Your username is set to - tmp
Demonstration des fflush
-Verhaltens mit der Funktion printf
in C
Beachten Sie, dass einige Streams (z. B. stderr
) nicht gepuffert sind. Im Gegensatz dazu ist die Funktion printf
, die implizit in den Stream stdout
schreibt, gepuffert, und wenn wir die Endlosschleife unter der Haube ausführen, die bei jeder Iteration ein einzelnes Zeichen druckt, wird sie den Inhalt erst dann in den Stream ausgeben, wenn der interne Puffer voll ist. Das folgende Codebeispiel führt also zum Burst-Druck der Aufzählungszeichen. Beachten Sie, dass wir die Funktion usleep
bei jeder Iteration aufrufen, um die Ausführung für das menschliche Auge deutlich sichtbar zu verlangsamen.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
printf(".");
usleep(1e3);
}
exit(EXIT_SUCCESS);
}
Wenn wir alternativ den Aufruf von printf
durch fprintf
ersetzen, das in den Stream stderr
druckt, ergibt sich das iterative Druckverhalten Zeichen für Zeichen jede Sekunde. Auch hier ist die 1-Sekunden-Verzögerung bei jeder Iteration nur dazu da, eine gute Demonstration zu gewährleisten.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
fprintf(stderr, ".");
sleep(1);
}
exit(EXIT_SUCCESS);
}
Wenn wir schließlich das gleiche Verhalten auf dem stdout
-Stream wie im vorherigen Beispielcode imitieren wollten, können wir den Aufruf fflush
nach der Funktion printf
hinzufügen. Dadurch wird erzwungen, dass die Puffer der C-Bibliothek bei jeder Iteration in die Kernel-Puffer geschrieben werden, was zu einem ähnlichen Verhalten führt.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
while (1) {
printf(".");
fflush(stdout);
sleep(1);
}
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook