stdout-Ausgabestrom in C leeren

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie die Funktion fflush, um den stdout-Ausgabestrom in C zu leeren
  2. Demonstration des fflush-Verhaltens mit der Funktion printf in C
stdout-Ausgabestrom in C leeren

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);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

Verwandter Artikel - C IO