[Home]
für Einsteiger!
Seite:  [1] 2 - Drucken

Inhalt:


Dateien

Wenn man Variablen oder Einstellungen auch nach dem Ende des Programmablaufs behalten möchte, muss man diese auf der Festplatte speichern. Dies geschieht in Form von Dateien. Dabei muss man zwischen Text- und Binärdateien unterscheiden, wobei erstere portabler sind als binäre und sich auch von Hand anpassen lassen.
 
Um mit Dateien arbeiten zu können, muss man "<fstream>" inkludieren. Danach stehen folgende Datentypen zur Verfügung:
  • ifstream (in Datei schreiben)
  • ofstream (aus Datei lesen)
  • fstream (lesen und schreiben)

Ein Handle

Um mit einer Datei arbeiten zu können, benötigen wir ein Dateihandle. Ein Handle ist eine Variable, die die Datei darstellt. Dieses Handle kann nun entweder vom Typ ifstream, ofstream oder fstream sein!
Quelltext
  1. #include <fstream>
  2. /*...*/
  3. std::fstream fdh; //Dateihandle erstellen
  4. std::ifstream idh; //Dateihandle erstellen
  5. std::ofstream odh; //Dateihandle erstellen
  6.  

Datei öffnen

Nun können wir diesem Handle eine Datei zuweisen:
Quelltext
  1. dh.open("test.txt", /*wie?*/);
  2.  

 
Für "wie" können wir nun folgende Werte einsetzen:
lesen ios::in
schreiben ios::out
Inhalt anhängen ios::app
Datei vorher löschen ios::trunc
Cursor ans Ende setzen ios::ate
Binäre (Daten-) Datei ios::binary

Mehrere dieser Eigenschaften kann man mit "|" verknüpfen. Um also eine Datei zum Schreiben zu öffnen, etwa ein Logfile, das zu Beginn geleert werden soll, müsste man schreiben:
Quelltext
  1. dh.open("logfile", std::ios::out|std::ios::trunc);
  2.  
  3. //Alternativ:
  4. ofstream log("test.log", std::ios::out|std::ios::trunc);
  5.  

 
Der zweite Parameter darf entfallen. Wird er nicht angegeben, werden die Standardwerte genutzt. Diese sind, je nach Typ des Handles:
ifstreamios::in
ofstreamios::out
fstreamios::in|ios::out

Nun sollte man noch überprüfen, ob die Datei erfolgreich geöffnet wurde. Dies geschieht am Besten durch:
Quelltext
  1. if ( dh.is_open() )
  2. {
  3. //Alles OK!
  4. }
  5.  

Datei lesen

Um eine Datei lesen zu können, solltest du natürlich "ios::in" verwenden. Danach kannst du den Inhalt mit den folgenden Funktionen problemlos auslesen. Dabei musst du dir vorstellen, dass du einen Cursor in der Datei bewegst, fast wie in einem Editor, der die Stelle angibt, an der du gerade liest! (Zum Ändern der Cursor-Position gleich noch mehr!)
Funktion Rückgabe Parameter Bemerkung
dh.get() char - Liest ein Zeichen
dh.getline(char*,int) - wohin und wie viele Zeichen maximal? Eine Zeile, oder max. Anzahl; liest auch Leerzeichen ein
dh >> string - - String wird gelesen, aber nur bis zum nächsten Leerzeichen/Zeilenumbruch (wie "cin")

Datei schreiben

Nachdem du die Datei mit "ios::out" geöffnet hast, kannst du mit den folgenden Funktionen in sie schreiben. Auch dabei musst du dir einen Cursor denken, der eine Position in der Datei angibt, an der du schreibst!
Funktion Parameter Bemerkung
dh.put(char) Zeichen Ein Zeichen
dh << string - String wird geschrieben, auch Leerzeichen (Wie "cout")!

Datei schließen

Um eine Datei zu schließen, und das Handle wieder gebrauchen zu können, muss man:
Quelltext
  1. dh.close();
  2.  

aufrufen. Nun wird die Datei auf die Festplatte geschrieben (Vorher wurde sie zum Schnellzugriff im RAM (Arbeitsspeicher) behalten). Um dieses Verhalten hervorzurufen, kann man auch:
Quelltext
  1. dh.flush();
  2.  

schreiben. Hierbei wird nur die Datei auf die Festplatte gebannt, dass Handle bleibt offen!

Den "Cursor" setzen - sich in der Datei orientieren

Um sich in einer Datei zu orientieren gibt es die folgenden Möglichkeiten. Dabei muss man zwischen Aus- und Eingabecursor unterscheiden!
Quelltext
  1. seekg(int); //[ifstream] setzt den Cursor
  2. seekp(int); //[ofstream]
  3.  
  4. int i=tellg(); //[ifstream] liefert die Position zurück
  5. int i=tellp(); //[ofstream]
  6.  

Die "seek"-Funktionen können außerdem einen weiteren Parameter haben (standardmäßig "ios::beg"), der angibt, von welchem Punkt ausgegangen werden soll. Von diesem Punkt wird dann der erste Parameter weitergezählt und der Cursor gesetzt!
Parameter Position, von der gelesen wird
ios::beg Dateianfang
ios::cur aktuelle Position
ios::end Dateiende

EOF - End of file und andere Flags

Flags sind "bool"-Werte, die einen Status beschreiben. Mit den folgenden "Funktionen" kannst du die Dateiarbeiten überwachen:
dh.bad() Gibt "true" zurück, wenn das Schreiben fehlschlägt, etwa weil keine Datei geöffnet ist oder kein Platz mehr vorhanden ist! Ist alles OK, wird "false" zurückgegeben.
dh.fail() Wie "bad()", aber gibt ebenfalls "true" zurück, wenn wir z.B. eine Zahl einlesen wollen, dort aber ein Buchstabe steht... Bei "false" ist alles OK.
dh.eof() Gibt "true" zurück, wenn das Dateiende erreicht wurde.
dh.good() Das wichtigste so genannte "Flag" (Alles in dieser Tabelle sind "Flags"): Gibt "true" zurück, wenn alle anderen oben genannten Werte "false" sind, also alles OK ist!
Oft wird "while(dh.good())" geschrieben, um eine Datei auszulesen...

Binäre Dateien

Da binäre Dateien nicht wie Textdateien schön formatiert sind, kommt man mit den oben genannten Methoden nicht weit. Zum Lesen oder Schreiben brauchen wir etwas neues: (Datei muss mit "ios::binary" geöffnet sein!)
Wie du weißt, hat ein "char" eine Größe von genau einem Byte. Eine Binärdatei kann sehr einfach und "byteweise" gelesen werden. Dazu benötigen wir die beiden folgenden Funktionen. Ein Beispiel findet sich auf der nächsten Seite:
Quelltext
  1. read(wohin, wieviel);
  2. write(woher, wieviel);
  3.  

"wohin" und "woher" sind Zeiger auf "char", oder der Name eines char-Arrays, wenn wir mehr als ein Byte einlesen wollen. "wieviel" ist dann die Größe in Byte!

Wie geht's weiter?

Nun folgen zwei Beispiele, eines zum Lesen und Schreiben von Textdateien, und eines zum Lesen und Schreiben von Binärdateien: Beispiele!
Seite:  [1] 2 - Drucken