Informatik I SS 2003 Dateioperationen 1 Textdateien, Öffnen Abspeichern und Einlesen von Texten (Strings) in Dateien 1. Das Öffnen einer Datei a) Deklaration eines Zeigers auf eine Datei FILE *pfile; b) Öffnen einer Datei und Zuweisen der Adresse pfile = fopen(dateiname, modus); pfile ist der Dateipositionszeiger. Er zeigt zu Beginn auf das erste Zeichen in der Datei, Lese- und Schreib-operationen ändern seinen Wert 2
Dateinamen und Pfade Angegeben als Stringkonstante (also in eingeschlossen) ohne Pfadangabe wird die Datei im Arbeitsverzeichnis angelegt Angabe des Pfades relativ zum Arbeitsverzeichnis oder absolut vom Laufwerk ausgehend Beispiel pfile = fopen( c:\\dokumente und Einstellungen\\UserXY\\Desktop\\Test.txt,w); erstellt auf dem Desktop des UsersXY eine Datei Namens Test.txt 3 Modi bei Textdateien Modus r w a w+ a+ Verhalten Öffnet eine Textdatei zum Lesen Erstellt eine Textdatei zum Schreiben. Der Inhalt einer evtl. existierenden Datei gleichen Namens wird gelöscht Erstellt oder öffnet eine bereits existierende Datei zum Schreiben. Der Dateipositionszeiger steht am Ende der Datei, neue Daten werden hinten angehängt Erstellt und öffnet eine Textdatei zum Lesen und Schreiben. Der Inhalt einer existierenden Datei gleichen Namens wird gelöscht Erstellt und öffnet eine Textdatei zum Lesen und Schreiben. Der Dateipositionszeiger steht am Ende der Datei, neue Daten werden hinten angehängt 4
Schreiben von Strings int fputs(const char *s, FILE *pfile); schreibt den String s in die Datei pfile die abschließende Null ( \0 )wird nicht mitgeschrieben die Zeile wird nicht mit ( \n ) abgeschlossen Rückgabewerte nicht negativ, falls erfolgreich ansonsten EOF (EOF i.d.r. -1) 5 Schreiben von einzelnen Zeichen int fputc (int c, FILE *pfile); c: Zeichen, das in die Datei geschrieben werden soll pfile: Zeiger auf File-Struktur Rückgabewerte: liefert das Zeichen c zurück, falls erfolgreich EOF, falls nicht erfolgreich (EOF i.d.r. -1) 6
Beispiel Schreiben eines Strings // Zeiger auf eine Datei deklarieren FILE *pfile; // Datei anlegen und zum Schreiben öffnen pfile = fopen( Testdatei.txt,w); // String definieren char mystring[]= Hallo World ; // und den ganzen String in die Datei schreiben fputs (mystring,pfile); // zum Zeilenabschluss noch ein `\n` schreiben fputs( \n,pfile); 7 Einlesen von Strings aus Dateien char *fgets(char *s,int n,file *pfile); s: String, in den die auszulesende Zeichenfolge geschrieben. Wird mit `\n` abgeschlossen n-1: maximale Anzahl der Zeichen, die ausgelesen werden. Lesevorgang wird abgebrochen, wenn `\n` oder das Ende der Datei erreicht ist pfile Zeiger auf File - Struktur Rückgabe: Zeiger s auf eingelesenen String, wenn erfolgreich NULL, falls nicht erfolgreich 11
Einlesen von einzelnen Zeichen aus Dateien int fgetc (FILE *pfile); pfile: Zeiger auf File-Struktur Rückgabewerte liefert den ausgelesenen Wert (als int!!) zurück, falls erfolgreich EOF falls nicht erfolgreich (EOF i.d.r -1) Vorsicht: Casting in char und anschließender Test auf EOF ist falsch 12 Dateipositionszeiger der Datentyp FILE definiert eine Struktur FILE (ist in stdio.h definiert) FILE *pfile erzeugt einen Zeiger auf eine derartige Struktur jeder Lese- und Schreibvorgang verändert die Position des Zeigers Schreibfunktionen: pfile zeigt auf die Stelle hinter dem zuletzt geschriebenen Zeichen Lesefunktionen : pfile zeigt auf die Position hinter dem zuletzt gelesenen Zeichen eine freie Positionierung des Filepointers ist bei Textdateien nicht möglich (Schreiben vom Anfang (Modus w) oder Ende (Modus a) Lesen nur sequentiell vom Anfang der Datei möglich 13
Erkennen des Dateiendes Das Dateiende kann man mit feof(pfile) erkennen int feof(file *pfile); pfile: Zeiger auf eine File-Struktur Rückgabewerte: 0 falls die Dateiposition das Ende der Datei erreicht hat 0 falls Dateiende noch nicht erreicht Vorsicht: feof(pfile) liefert erst dann einen Wert 0, wenn mindestens 1 Leseversuch fehlgeschlagen ist 14 fprintf und fscanf (Textdateien) fprintf und fscanf erlauben formatiertes Schreiben und Lesen von Dateien Syntax ähnlich printf, scanf int fprintf (FILE *pfile, char *Format, arg1,arg2..); int fscanf(file *pfile,char *Format, arg1, agr2, ); 17
Benutzung von fscanf und fprintf Beispielaufruf fprintf fprintf (pfile, Der Wert von %s ist %f\n, Variable 1,5.20); schreibt in die Datei pfile Der Wert von Variable 1 ist 5.2\n Beispielaufruf fscanf fscanf( %i%s%i,&a, mystring,&b); Eingabe > 75 Test 80 wobei a und b als int und mystring als ausreichend großes char-feld vereinbart sein muss 18 Binärdateien Binärdateien speichern Variablen und Werte nicht als geschriebene Zahlen (oder Zeichen), sondern direkt den Inhalt der Bytes, den diese Variablen repräsentieren Vorteile meist wird weniger Speicherplatz benötigt umwandeln von Texten in Variablen (fscan) entfällt Manipulation des Dateipositionszeiger möglich Nachteile Dateien sind nicht lesbar (z.b. mit Texteditor) 19
Modi bei Binärdateien Modus rb wb ab wb+ Verhalten Öffnet eine Binärdatei zum Lesen Erstellt eine Binärdatei zum Schreiben. Der Inhalt einer existierenden Datei gleichen Namens wird gelöscht Erstellt oder öffnet eine bereits existierende Binärdatei zum Schreiben. Der Dateipositionszeiger steht am Ende der Datei, neue Daten werden hinten angehängt Erstellt und öffnet eine Binärdatei zum Lesen und Schreiben. Der Inhalt einer existierenden Datei gleichen Namens wird gelöscht ab+ Erstellt und öffnet eine Binärdatei zum Lesen und Schreiben. Der Dateipositionszeiger steht am Ende der Datei, neue Daten werden hinten angehängt 20 fwrite size_t fwrite (const void *ptr,size_t size, size_t anz, FILE *pfile); ptr: size: anz: pfile: Zeiger auf ein Feld, von dem geschrieben werden soll Größe eines Blockes in Bytes Anzahl der Blöcke Zieger auf Binärfile Rückgabewerte Anzahl der geschriebenen Blöcke (falls der Rückgabewert = anz ist, war Schreiben erfolgreich, bei Werten <anz wurde abgebrochen 21
fread size_t fread (void *ptr,size_t size, size_t anz, FILE *pfile); ptr: size: anz: pfile: Zeiger auf ein Feld, in das geschrieben werden soll Größe eines Blockes in Bytes Anzahl der Blöcke, die gelesen werden sollen Zeiger auf Binärfile Rückgabewerte Anzahl der gelesenen Blöcke (falls der Rückgabewert = anz ist, war Schreiben erfolgreich, bei Werten <anz wurde abgebrochen 22 Arbeiten mit dem Dateipositionszeiger Bei Binärdateien kann man den Wert des Dateipositionszeigers ändern wahlfreier Zugriff auf einzelne Blocks innerhalb der Binärdatei Setzen des Positionszeigers int fsetpos(file *pfile, fpos_t &position); fpos_t : &positon ein in stdio.h mit typedef definierter Datentyp Adresse eines Variablen vom Typ fpos_t, in der der die neue (Wunsch-)Position des Filezeigers steht Rückgabewert: 0, falls erfolgreich, >0, falls nicht erfolgreich 27
Bestimmen des Dateipositionszeigers int fgetpos(file *pfile,fpos_t *position); pfile: position: Zeiger auf ein Binärfile Variable vom Typ fpos_t, in der nach Verlassen der Funktion die Position des Dateizeigers steht Rückgabewert: 0, falls erfolgreich, sonst einen Wert >0 30 fwrite size_t fwrite (const void *ptr,size_t size, size_t anz, FILE *pfile); ptr: size: anz: pfile: Zeiger auf ein Feld, von dem geschrieben werden soll Größe eines Blockes in Bytes Anzahl der Blöcke Zieger auf Binärfile Rückgabewerte Anzahl der geschriebenen Blöcke (falls der Rückgabewert = anz ist, war Schreiben erfolgreich, bei Werten <anz wurde abgebrochen 31
fread size_t fread (void *ptr,size_t size, size_t anz, FILE *pfile); ptr: size: anz: pfile: Zeiger auf ein Feld, in das geschrieben werden soll Größe eines Blockes in Bytes Anzahl der Blöcke, die gelesen werden sollen Zeiger auf Binärfile Rückgabewerte Anzahl der gelesenen Blöcke (falls der Rückgabewert = anz ist, war Schreiben erfolgreich, bei Werten <anz wurde abgebrochen 32 Arbeiten mit dem Dateipositionszeiger Bei Binärdateien kann man den Wert des Dateipositionszeigers ändern wahlfreier Zugriff auf einzelne Blocks innerhalb der Binärdatei Setzen des Positionszeigers int fsetpos(file *pfile, fpos_t &position); fpos_t : ein in stdio.h mit typedef definierter Datentyp &positon Adresse eines Variablen vom Typ fpos_t, in der der die neue (Wunsch-)Position des Filezeigers steht Rückgabewert: 0, falls erfolgreich, >0, falls nicht erfolgreich 33
Arbeiten mit fseek int fseek(file *pfile,long distanz, int modus) ; pfile: Zeiger auf ein Binärfeile distanz: Distanz (in Byte), um die der Zeiger verändert werden soll modus: 3 Modi stehen zur Verfügung: Modus Beschreibung SEEK_SET SEEK_END SEEK_CUR Positionszeiger am Anfang, distanz wird dazugezählt (distanz muss >0 sein) Positionszeiger am Ende, distanz wird dazugezählt (distanz muss <0 sein) Zum akt. Positionszeiger wird distanz dazugezählt (distanz darf >0 und < 0 sein) die Makros obiger Modi sind in stdio.h definiert 34 Weitere Dateioperationen Setzen des Positionszeigers auf den Anfang der Datei void rewind(file *pfile); Schließen und Öffnen einer Datei FILE *freopen(const char *name, const char *modus, File *pfile);..schließt pfile und öffnet name im Modus modus Löschen einer Datei int remove(const char *name); löscht die Datei name gibt bei Erfolg 0 zurück, ansonsten einen Wert 0 37
Weitere Dateioperationen Umbenennen einer Datei int rename (const char *altname, const char *neuname); benennt die Datei altname in neuname um gibt bei Erfolg 0 zurück, ansonsten einen Wert 0 38 Temporäre Dateien beim Anlegen temporärer Dateien wird eindeutiger Name benötigt, der keinen Konflikt mit bereits bestehenden Namen erzeugt char *tmpnam(char *s); erzeugt einen Dateinamen, den noch nicht existiert s muss mind L_tempnam Zeichen groß sein (L_tempnam ist in stdio.h definiert) s kann auch Null-Zeiger sein, dann reserviert tmpnam einen eigenen Speicherbereich jeder Aufruf generiert einen neuen Dateinamen 39