18.12 Gelesenes Zeichen in die Eingabe zurück-schieben – ungetc
 
Mit der Funktion ungetc() können Sie das zuletzt gelesene Zeichen wieder zurück in den Stream schieben. Die Syntax:
#include <stdio.h>
int ungetc(int ch, FILE *datei);
ungetc() schiebt das zuletzt mit der Funktion fgetc() oder fread() gelesene Zeichen ch in den Stream datei zurück. Im Fall eines Fehlers gibt diese Funktion EOF zurück. Damit ist das Zeichen ch das erste, das beim nächsten Lesen aus dem Stream datei wieder gelesen wird.
Dies gilt allerdings nicht mehr, wenn vor dem nächsten Lesevorgang eine der Funktionen fflush(), rewind(), fseek() oder fsetpos() aufgerufen wurde.
Ein Beispiel zu ungetc(). Das Auslesen einer ständig wachsenden Textdatei. Das Programm liest zeichenweise aus einem Stream und gibt diese auch zeichenweise wieder auf die Standardausgabe aus, bis EOF erreicht wird. Anschließend wird das zuletzt gelesene Zeichen (nicht EOF) wieder zurück in den Stream geschoben. Das Ganze wird in einer Endlosschleife ausgeführt. Hier der Code dazu:
/* grown_file.c */
#include <stdio.h>
#include <stdlib.h>
/* Bitte anpassen */
#define DATEI "datei.txt"
int main(void) {
FILE *fp;
int c;
fp = fopen(DATEI, "r");
if(fp == NULL) {
fprintf(stderr, "Konnte %s nicht öffnen\n", DATEI);
return EXIT_SUCCESS;
}
while(1) {
while(c=fgetc(fp)) { /* Zeichenweise einlesen */
if(c == EOF) /* Ist es EOF */
ungetc(c,fp); /* Letztes Zeichen zurück */
else
fputc(c, stdout); /* Ausgeben */
}
}
/* Wird nie erreicht */
fclose(fp);
return EXIT_SUCCESS;
}
Bei diesem Listing wird davon ausgegangen, dass eine Datei mit dem Namen »datei.txt« im selben Verzeichnis wie das Listing existiert. Der Inhalt dieser Datei sei folgender:
Eine Zeile in der Textdatei
Die zweite Zeile ist diese hier
Übersetzen Sie das Listing und starten das Programm. Öffnen Sie jetzt die Textdatei »datei.txt« und fügen Sie einen weiteren Text ein. Zum Beispiel:
Eine Zeile in der Textdatei
Die zweite Zeile ist diese hier
Diese Zeile ist neu hinzugekommen
Speichern Sie diesen Text wieder und beachten Sie die weitere Ausführung des Programms. Die neu hinzugekommene Zeile wird ebenfalls ausgegeben. Theoretisch ließen sich damit in einem Netzwerk einzelne Dateien überwachen. Statt der Ausgabe auf dem Bildschirm, könnte hierfür eine Nachricht an den Administrator geschickt werden.
Vermutlich stellen Sie sich die Frage, wie es möglich ist, dass trotz eines EOF-Flags das Programm tadellos arbeitet, ohne bspw. die Funktion clearerr() aufzurufen. Das liegt daran, dass die Funktion ungetc() das EOF-Flag löscht und somit immer wieder nach dem Erreichen des Dateiendes ein Zeichen zurückschieben kann. ungetc() kann aber keine EOF-Konstante zurückschieben.
|