C Standard-BibliothekEin- und Ausgabe: <stdio.h>
Die Ein- und Ausgabefunktionen, Typen und Makros, die in <stdio.h> vereinbart sind, machen nahezu ein Drittel der Bibliothek aus. Ein Datenstrom (stream) ist Quelle oder Ziel von Daten und wird mit einer Platte oder einem anderen Peripheriegerät verknüpft. Die Bibliothek unterstützt zwei Arten von Datenströmen, für Text und binäre Information, die allerdings bei manchen Systemen und insbesondere bei UNIX identisch sind. Ein Textstrom ist eine Folge von Zeilen; jede Zeile enthält null oder mehr Zeichen und ist mit '\n' abgeschlossen. Eine Umgebung muß möglicherweise zwischen einem Textstrom und einer anderen Repräsentierung umwandeln (also zum Beispiel '\n' als Wagenrücklauf und Zeilenvorschub abbilden). Wird ein Binärstrom geschrieben und auf dem gleichen System wieder eingelesen, so entsteht die gleiche Information. Ein Strom wird durch Eröffnen (open) mit einer Datei oder einem Gerät verbunden; die Verbindung wird durch Abschließen (close) wieder aufgehoben. Eröffnet man eine Datei, so erhält man einen Zeiger auf ein Objekt vom Typ FILE, wo alle Information hinterlegt ist, die zur Kontrolle des Stroms nötig ist. Wenn die Bedeutung eindeutig ist, werden wir die Begriffe FILE-Zeiger und Datenstrom gleichberechtigt verwenden. Wenn die Ausführung eines Programms beginnt, sind die drei Ströme stdin, stdout und stderr bereits eröffnet.
DateioperationenDie folgenden Funktionen beschäftigen sich mit Dateioperationen. Der Typ size_t ist der vorzeichenlose, ganzzahlige Resultattyp des sizeof-Operators.FILE *fopen(const char *filename, const char *mode)fopen eröffnet die angegebene Datei und liefert einen Datenstrom oder NULL bei Mißerfolg. Zu den erlaubten Werten von mode gehören
FILE *freopen(const char *filename, const char *mode, FILE *stream)freopen eröffnet die Datei für den angegebenen Zugriff mode und verknüpft stream damit. Das Resultat ist stream oder Null bei einem Fehler. Mit freopen ändert man normalerweise die Dateien, die mit stdin, stdout oder stderr verknüpft sind. int fflush(FILE *stream)Bei einem Ausgabestrom sorgt fflush dafür, daß gepufferte, aber noch nicht geschriebene Daten geschrieben werden; bei einem Eingabestrom ist der Effekt undefiniert. Die Funktion liefert EOF bei einem Schreibfehler und sonst Null. fflush(NULL) bezieht sich auf alle offenen Dateien. int fclose(FILE *stream)fclose schreibt noch nicht geschriebene Daten für stream, wirft noch nicht gelesene, gepufferte Eingaben weg, gibt automatisch angelegte Puffer frei und schließt den Datenstrom. Die Funktion liefert EOF bei Fehlern und sonst Null. int remove(const char *filename)remove entfernt die angegebene Datei, so daß ein anschließender Versuch, sie zu eröffnen, fehlschlagen wird. Die Funktion liefert bei Fehlern einen von Null verschiedenen Wert. int rename(const char *oldname, const char *newname)rename ändert den Namen einer Datei und liefert nicht Null, wenn der Versuch fehlschlägt. FILE *tmpfile(void)tmpfile erzeugt eine temporäre Datei mit Zugriff "wb+", die automatisch gelöscht wird, wenn der Zugriff abgeschlossen wird, oder wenn das Programm normal zu Ende geht. tmpfile liefert einen Datenstrom oder NULL, wenn die Datei nicht erzeugt werden konnte. char *tmpnam(char s[L_tmpnam])tmpnam(NULL) erzeugt eine Zeichenkette, die nicht der Name einer existenten Datei ist, und liefert einen Zeiger auf einen internen Vektor im statischen Speicherbereich. tmpnam(s) speichert die Zeichenkette in s und liefert auch s als Resultat; in s müssen wenigstens L_tmpnam Zeichen abgelegt werden können. tmpnam erzeugt bei jedem Aufruf einen anderen Namen; man kann höchstens von TMP_MAX verschiedenen Namen während der Ausführung des Programms ausgehen. Zu beachten ist, daß tmpnam einen Namen und keine Datei erzeugt. int setvbuf(FILE *stream, char *buf, int mode, size_t size)setvbuf kontrolliert die Pufferung bei einem Datenstrom; die Funktion muß aufgerufen werden, bevor gelesen oder geschrieben wird, und vor allen anderen Operationen. Hat mode den Wert_IOFBF, so wird vollständig gepuffert, _IOLBF sorgt für zeilenweise Pufferung bei Textdateien und _IONBF verhindert Puffern. Wenn buf nicht NULL ist, wird buf als Puffer verwendet; andernfalls wird ein Puffer angelegt. size legt die Puffergröße fest. Bei einem Fehler liefert setvbuf nicht Null. void setbuf(FILE *stream, char *buf)Wenn buf den Wert NULL hat, wird der Datenstrom nicht gepuffert. Andernfalls ist setbuf äquivalent zu (void) setvbuf(stream, buf, _IOFBF, BUFSIZ).
Formatierte AusgabeDie printf-Funktionen ermöglichen Ausgabe-Umwandlungen unter Formatkontrolle.int fprintf(FILE *stream, const char *format, ...)fprintf wandelt Ausgaben um und schreibt sie in stream unter Kontrolle von format. Der Resultatwert ist die Anzahl der geschriebenen Zeichen; er ist negativ, wenn ein Fehler passiert ist. Die Format-Zeichenkette enthält zwei Arten von Objekten: gewöhnliche Zeichen, die in die Ausgabe kopiert werden, und Umwandlungsangaben, die jeweils die Umwandlung und Ausgabe des nächstfolgenden Arguments von fprintf veranlassen. Jede Umwandlungsangabe beginnt mit dem Zeichen % und endet mit einem Umwandlungszeichen. Zwischen % und dem Umwandlungszeichen kann, der Reihenfolge nach, folgendes angegeben werden:
Als Feldbreite oder Genauigkeit kann jeweils * angegeben werden; dann wird der Wert durch Umwandlung von dem nächsten oder den zwei nächsten Argumenten festgelegt, die den Typ int besitzen müssen. Die Umwandlungszeichen und ihre Bedeutung erklärt Tabelle 1. Wenn das Zeichen nach % kein Umwandlungszeichen ist, ist der Verlauf undefiniert. int printf(const char *format, ...)printf(...) ist äquivalent zu fprintf(stdout,...). int sprintf(char *s, const char *format, ...)sprintf funktioniert wie printf, nur wird die Ausgabe in den Zeichenvektor s geschrieben und mit '\0' abgeschlossen. s muß groß genug für das Resultat sein. Im Resultatwert wird '\0' nicht mitgezählt. vprintf(const char *format, va_list arg) vfprintf(FILE *stream, const char *format, va_list arg) vsprintf(char *s, const char *format, va_list arg)Die Funktionen vprintf, vfprintf und vsprintf sind äquivalent zu den entsprechenden printf-Funktionen, jedoch wird die variable Argumentliste durch arg ersetzt. Dieser Wert wird mit dem Makro va_startund vielleicht mit Aufrufen von va_arg initialisiert. Siehe dazu die Beschreibung von <stdarg.h> im Abschnitt Variable Argumentenliste.
Formatierte EingabeDie scanf-Funktionen behandeln Eingabe-Umwandlungen unter Formatkontrolle.int fscanf(FILE *stream, const char *format, ...)fscanf liest von stream unter Kontrolle von format und legt umgewandelte Werte mit Hilfe von nachfolgenden Argumenten ab, die alle Zeiger sein müssen. Die Funktion wird beendet, wenn format abgearbeitet ist. fscanf liefert EOF, wenn vor der ersten Umwandlung das Dateiende erreicht wird oder ein Fehler passiert; andernfalls liefert die Funktion die Anzahl der umgewandelten und abgelegten Eingaben. Die Format-Zeichenkette enthält normalerweise Umwandlungsangaben, die zur Interpretation der Eingabe verwendet werden. Die Format-Zeichenkette kann folgendes enthalten:
Eine Umwandlungsangabe bestimmt die Umwandlung des nächsten Eingabefelds. Normalerweise wird das Resultat in der Variablen abgelegt, auf die das zugehörige Argument zeigt. Wenn jedoch * die Zuweisung verhindern soll, wie bei %*s, dann wird das Eingabefeld einfach übergangen und eine Zuweisung findet nicht statt. Ein Eingabefeld ist als Folge von Zeichen definiert, die keine Zwischenraumzeichen sind; es reicht entweder bis zum nächsten Zwischenraumzeichen, oder bis eine explizit angegebene Feldbreite erreicht ist. Daraus folgt, daß scanf über Zeilengrenzen hinweg liest, um seine Eingabe zu finden, denn Zeilentrenner sind Zwischenraumzeichen. (Zwischenraumzeichen sind Leerzeichen, Tabulatorzeichen \t, Zeilentrenner \n, Wagenrücklauf \r, Vertikaltabulator \v und Seitenvorschub \f). Das Umwandlungszeichen gibt die Interpretation des Eingabefelds an. Das zugehörige Argument muß ein Zeiger sein. Die erlaubten Umwandlungszeichen zeigt Tabelle 2. Den Umwandlungszeichen d, i, n, o, u und x kann h vorausgehen, wenn das Argument ein Zeiger auf short statt int ist, oder der Buchstabe l, wenn das Argument ein Zeiger auf long ist. Vor den Umwandlungszeichen e, f und g kann der Buchstabe l stehen, wenn ein Zeiger auf double und nicht auf float in der Argumentliste steht, und L, wenn es sich um einen Zeiger auf long double handelt. int scanf(const char *format, ...) scanf(...) ist äquivalent zu fscanf(stdin,...). int sscanf(const char *s, const char *format, ...) sscanf(s, ...) ist äquivalent zu scanf(...), mit dem Unterschied, daß die Eingabezeichen aus der Zeichenkette s stammen.
Ein- und Ausgabe von Zeichenint fgetc(FILE *stream)
fgetc liefert das nächste Zeichen aus stream als unsigned char (umgewandelt in int) oder EOF bei Dateiende oder bei einem Fehler.
fgets liest höchstens die nächsten n-1 Zeichen in s ein und hört vorher auf, wenn Zeilentrenner gefunden wird. Der Zeilentrenner wird im Vektor abgelegt. Der Vektor wird mit '\0' abgeschlossen. fgets liefert s oder NULL bei Dateiende oder bei einem Fehler.
fputc schreibt das Zeichen c (umgewandelt in unsigned char) in stream. Die Funktion liefert das ausgegebene Zeichen oder EOF bei Fehler.
getc ist äquivalent zu fgetc, kann aber ein Makro sein und dann das Argument für stream mehr als einmal bewerten.
putc ist äquivalent zu fputc, kann aber ein Makro sein und dann das Argument für stream mehr als einmal bewerten.
putchar(c) ist äquivalent zu putc(c, stdout).
puts schreibt die Zeichenkette s und einen Zeilentrenner in stdout. Die Funktion liefert EOF, wenn ein Fehler passiert, andernfalls einen nicht-negativen Wert.
ungetc stellt c (umgewandelt in unsigned char) in stream zurück, von wo das Zeichen beim nächsten Lesevorgang wieder geholt wird. Man kann sich nur darauf verlassen, daß pro Datenstrom ein Zeichen zurückgestellt werden kann. EOF darf nicht zurückgestellt werden. ungetc liefert das zurückgestellte Zeichen oder EOF bei einem Fehler.
fread liest aus stream in den Vektor ptr höchstens nobj Objekte der Größe size ein. fread liefert die Anzahl der eingelesenen Objekte; das kann weniger als die geforderte Zahl sein. Der Zustand des Datenstroms muß mit feof und ferror untersucht werden.
fwrite schreibt nobj Objekte der Größe size aus dem Vektor ptr in stream. Die Funktion liefert die Anzahl der ausgegebenen Objekte; bei Fehler ist das weniger als nobj.
fgetpos speichert die aktuelle Position für stream bei *ptr. Der Wert kann später mit fsetpos verwendet werden. Der Datentyp fpos_t eignet sich zum Speichern von solchen Werten. Bei Fehler liefert fgetpos einen von Null verschiedenen Wert.
Viele der Bibliotheksfunktionen notieren Zustandsangaben, wenn ein Dateiende oder ein Fehler gefunden wird. Diese Angaben können explizit gesetzt und getestet werden. Außerdem kann der Integer-Ausdruck errno (der in <errno.h> deklariert ist) eine Fehlernummer enthalten, die mehr Information über den zuletzt aufgetretenen Fehler liefert.
|
15. November 1999, Peter Klingebiel, DVZ |