16.12 Gelesenes Zeichen in die Eingabe zurückschieben – »ungetc()« 

Mit der Funktion ungetc() können Sie das zuletzt gelesene Zeichen wieder zurück in den Stream schieben. Die Syntax lautet:
#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() wäre das Auslesen einer ständig wachsenden Textdatei. Das Programm liest zeichenweise aus einem Stream und gibt die Daten 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 sehen Sie den 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 Sie 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. Anstelle 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 beispielsweise 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.
Auch hierfür gibt es wieder die Version für breite Zeichen mit folgender Syntax:
#include <wchar.h> wint_t ungetwc( wint_t wc, FILE *fp );
Anstatt EOF wird hier im Fehlerfall natürlich WEOF zurückgeliefert. Ansonsten gilt dasselbe wie bei der byte-orientierten Version ungetc().
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.