Ein- und Ausgabebibliothek
Zusammen mit der Sprachdefinition wuchs auch eine Definition der so genannten streams- Bibliothek. Ein "stream ist am besten mit Verbindung (oder Kanal) zu beschreiben. So kann man eine Verbindung zu einem Gerät, einer Datei oder einem Bytefeld herstellen. Die Verbindung oder besser das Verbindungsobjekt, kann im Rahmen der Ein- und Ausgabe weitere Dienstleistungen erbringen. Im Normalfall ist dies die Pufferung und die Formatierung.
Das Objekt, das die Ein- und Ausgabe bearbeitet, wird mit einer der Klassen aus der Klassenbibliothek angelegt. Diese Klassen bilden Hierarchien. Für jede der drei Grundverbindungen seriell (z. B. Tastatur), Dateibearbeitung und Pseudoein- und Ausgabe im Speicher (ähnlich sprintf() ) gibt es eine Klassenhierarchie.
Alle Hierarchien folgen einem einheitlichen Schema. Ausgehend von der Basisklasse "ios" leitet man Klassen für die Eingabe oder die Ausgabe ab. Mit diesen beiden Klassen bildet man schließlich eine Klasse, die sowohl Ein- wie Ausgabe behandeln kann.
|
Ein- und Ausgabebibliothek Seite 207 |
Arbeiten mit Dateien
Zum Arbeiten mit Dateien gehört:
Schauen wir uns wieder ein Beispiel an. Das Programm soll eine Datei kopieren. In der Informationsdatei fstream.h sind die Klassen ifstream für Eingabe, ofstream für Ausgabe und fstream vordefiniert. fstream kann für Ein- und Ausgabe verwendet werden.
|
Seite 208 Einsteigerseminar C++ |
Das Öffnen kann man wahlweise beim Anlegen eines Verbindungsobjektes mit einem Konstruktor oder durch eine Methode open() erledigen. Die Art der Verbindung kann mit Konstanten aus einem enum- Datentyp der Basisklasse ios angegeben werden. Das Schließen einer Verbindung geschieht durch den Destruktor oder die parameterlose Methode close().
Im Beispiel wird eine Datei im Textmodus (default) eröffnet. Der Operator ! ist überladen und liefert eine Fehlerabfrage. Bei einem Fehler wird das Programm abgebrochen.
Beim Öffnen können folgende Konstante auch miteinander verodert verwendet werden. Die Definition erfolgt in der Klasse ios.
Bei der Benutzung wird dem Konstantennamen der Klassenname ios vorangestellt. ios ist die Basisklasse eines streams.
Der Fehlertest nach dem Eröffnen erfolgt wieder mit Hilfe des überlagerten Operators !. Mit Hilfe von ! wird eine Statusabfragemethode der Klasse "ios" aufgerufen. Falls ein Fehler aufgetreten ist, liefert ! den logischen Wert wahr.
|
Ein- und Ausgabebibliothek Seite 209 |
Die zweite Art, den Status eines E/A- Objektes zu erhalten, liefert die Typkonvertierung. In der while Schleife (Zeile 17) haben wir sie verwendet.
Bei der Ausgabedateiverbindung wird die "open()"-Methode benutzt. Die Fehlerabfrage verwendet wieder den überlagerten !-Operator. Beachten Sie, daß bei der Definition der Typkonvertierung kein Rückgabetyp angegeben wird.
Die Positionierung kann getrennt für Eingabe- und Ausgabe erfolgen. Es gibt Methoden zum Lesen und Setzen.
Statustest
Der Status einer Verbindung wird in der Basisklasse ios in einer Statusvariablen gehalten und kann mit einem Satz von inline-Methoden abgefragt werden.
|
Seite 210 Einsteigerseminar C++ |
Die Abfragemethoden sind in der Basisklasse definiert. Sie können daher für beliebige E/A- Objekte benutzt werden. In unserem Beispiel werden die Abfragemethoden innerhalb der Typkonvertierung oder des überlagerten !-Operators benutzt. Eine spezielle Rolle spielt clear(). Einerseits löscht clear() den Status, wenn sein Parameter den Wert 0" hat. Andererseits kann der Parameterwert zum Setzen des gesamten Statuswortes benutzt werden. Da die Abfragemethoden zur Basisklasse gehören, können sie auch für alle abgeleiteten Objekte benutzt werden.
Formatfreie E/A
Die eigentliche Arbeit erledigt die while-Schleife mit Hilfe zweier Methoden der Basisklasse, die ohne Formatierung arbeiten.
|
Ein- und Ausgabebibliothek Seite 211 |
Im Test der while-Schleife werden die Zustände beider E/A- Objekte mit einer Typkonvertierung abgefragt. Die Konvertierung geschieht von der Klasse auf (void *). Dafür existiert eine Konvertierungsmethode. Die Methode fragt die Statusbits ab und meldet wahr zurück, fall der Status OK ist. Die verwendete get-Methode liefert das bearbeitete Objekt mit eine Referenz zurück (eingabe). Die Typkonvertierungen für beide Objekte müssen OK melden, damit die Schleife weiterläuft.
In iostream.h sind noch weitere Methoden deklariert und definiert. Dazu gehören Methoden zum Lesen von Zeilen, Worten oder zu überlesenden Zeichen.
Formatierung der Verbindung - Manipulatoren
Für die Formatierung steht in der Basisklasse "ios" ebenfalls ein Feld zur Verfügung. Und wieder gibt es eine Anzahl von Methoden, die dieses Feld auswerten oder setzen. Sie heißen Manipulatoren.
|
Seite 212 Einsteigerseminar C++ |
Die Manipulatoren wirken normalerweise nur für die nächste Ausgabe. Die Ausnahmen sind die Manipulatoren, die die Ausgabebasis ändern.
Mit Hilfe der Manipulatoren mit Parametern können Füllzeichen oder die Breite des Ausgabefeldes eingestellt werden. Die Angabe gilt immer nur für die jeweils nächste Ausgabe. Mit Hilfe der Manipulatoren setiosflags und resetiosflags können die einzelnen Bits des Statusfeldes gezielt gesetzt oder gelöscht werden. Die Bits können ver-odert werden. (siehe Bild 15-12)
|
Ein- und Ausgabebibliothek Seite 213 |
Rahmen21
Noch ein Beispiel mit verschiedenen Zahlenbasen.
|
Seite 214 Einsteigerseminar C++ |
Die Manipulatoren gelten für oder / und für die Ausgabe wie im Bild 15-11 angegeben.
Die I/O-Bibliothek bietet so viele Möglichkeiten, daß gar nicht alle Varianten im Rahmen des Buches dargestellt werden konnten.
Bitte lesen Sie bei Bedarf die Compilerdokumentationen oder im zugehörigen Hilfesystem.
|
Ein- und Ausgabebibliothek Seite 215 |
Hinweise zur Weiterarbeit
1) Schreiben Sie zwei Filterprogramme, die zur Umsetzung von DOS-Textdateien nach und umgekehrt dienen Können. Wandeln Sie dazu das Programm im Bild 15-2 ab. Der Unterschied bestehtim unterschiedlichen Zeilenende. DOS-Dateien beenden eine Zeile mit CR und LF. (0x0d und 0x0a). UNIX-Dateien kennen nur ein LF (0x0a).
2) Legen Sie mit Hilfe der Manipulatoren im Bild 15-11 und der möglichen im Bild 15-10 die Ausgabe einer Tabelle an. Die einzelnen Felder der Tabelle sollen formatiert ausgegeben werden. Als Vorbild kann auch das Bild 15-13 dienen.
Im nächsten Kapitel
Auch in streng typorientierten Sprachen benötigen wir gelegentlich die Möglichkeit, Variable als Variable eines andern Typs zu betrachten.
Das folgende Kapitel gibt einen Überblick über Typkonvertierung in C++.
|
Seite 216 Einsteigerseminar C++ |