In diesem Abschnitt werden die Operatoren beschrieben, die sowohl für die Ein- als auch für die Ausgabe definiert sind. #include <iostream.h> class ios enum enum tabexp}; enum /* Flags zur Formatsteuerung */ skipws=01, }; static const long basefield; /* dec | oct | hex */ static const long adjustfield; /* left | right | internal */ static const long floatfield; /* scientific | fixed */ public: ios(streambuf*);
protected: ios(); init(streambuf*); private: ios(ios&);void }; /* Manipulatoren */
| |||||||||
Die aus ios abgeleiteten stream-Klassen stellen eine Schnittstelle auf sehr hoher Ebene zur Verfügung, über die formatierte wie auch unformatierte Informationen in und aus streambuf-Objekten übertragen werden können. In der Klasse ios sind Aufzählungen (open_mode, io_state und seek_dir) und Formatflags deklariert, um den globalen Namensbereich durch diese Informationen nicht zu belasten. io_state wird in diesem Abschnitt unter der Überschrift Fehlerstatus beschrieben. Die Formatfelder werden ebenfalls in diesem Abschnitt - im Absatz über die Formatierung - erläutert. Erklärungen zu open_mode finden Sie im Abschnitt zu fstreambei der Funktion open(), und zusätzliche Informationen zu seek_dir werden im Abschnitt zu sbufpub bei der Funktion seekoff() gegeben. Bei den folgenden Erläuterungen wird vorausgesetzt, dass
Konstruktoren und Zuweisungios(streambuf * sb) Das durch sb bezeichnete streambuf-Objekt wird zu dem streambuf-Objekt, das mit dem angelegten ios-Objekt verknüpft ist. Das Programmverhalten ist für sb gleich 0 nicht definiert. ios(ios& sr) Das Kopieren von ios-Objekten ist allgemein nicht genau definiert, deshalb sind die Konstruktoren und Zuweisungsoperatoren als private deklariert. Der Compiler gibt bei einem Versuch, ios-Objekte zu kopieren, Meldungen aus. Gewöhnlich werden Zeiger auf iostream-Objekte kopiert. ios() Da die Klasse ios als virtuelle Basisklasse vererbt wird, muß ein Konstruktor ohne Argumente eingesetzt werden. Der Konstruktor wird als protected deklariert. Aus diesem Grund ist ios::init(streambuf*) als protected deklariert und muß für die Initialisierung abgeleiteter Klassen eingesetzt werden. FehlerstatusEin ios-Objekt besitzt einen internen Fehlerstatus, der aus mehreren Bits besteht, die als io_state deklariert sind. Die Elementfunktionen, die sich mit der Fehlerstatusangabe beschäftigen, sind: int i=s.rdstate() Der aktuelle Fehlerstatus wird geliefert. s.clear(int i) Der Wert i wird als Fehlerstatus gespeichert. Wenn der Wert von i gleich 0 ist, werden alle Bits gelöscht. Um ein Bit ohne gleichzeitiges Löschen zuvor gesetzter Bits zusetzen, wird eine Programmzeile in der Form s.clear(ios::badbit|s.rdstate()) benötigt. int i=s.good() Es wird ein Wert ungleich 0 geliefert, wenn im Fehlerstatus keine Bits gesetzt sind.Anderenfalls wird der Wert 0 geliefert. int i=s.eof() Es wird ein Wert ungleich 0 geliefert, wenn eofbit im Fehlerstatus gesetzt ist. Ansonsten wird der Wert 0 geliefert. Das Bit wird üblicherweise gesetzt, wenn das Dateiende bei der Entnahme von Zeichen erreicht wurde. int i=s.fail() Es wird ein Wert ungleich 0 geliefert, wenn entweder badbit oder failbit im Fehlerstatus gesetzt sind. Im anderen Fall wird der Wert 0 zurückgegeben. Dies deutet üblicherweise darauf hin, dass eine Extraktion oder Konvertierung erfolglos verlaufen ist,der Datenstrom aber weiterhin eingesetzt werden kann. Nach dem Löschen von failbit können im allgemeinen weitere Ein- und Ausgaben für s ausgeführt werden. int i=s.bad() Es wird ein Wert ungleich 0 geliefert, wenn badbit im Fehlerstatus gesetzt ist. Im anderen Fall wird der Wert 0 zurückgegeben. Dies deutet üblicherweise darauf hin, dass eine Operation auf s.rdbuf() erfolglos verlaufen ist - ein schwerwiegender Fehler,der häufig nicht behoben werden kann. Weitere Ein- und Ausgabeoperationen für s können wahrscheinlich nicht ausgeführt werden. OperatorenEs sind zwei Operatoren definiert, die eine komfortable Prüfung des Fehlerstatus eine sios-Objektes ermöglichen: operator!() und operator void*() bzw. operator const void*() const. Der zweite Operator wandelt ein ios-Objekt in einen Zeiger um, so dass dieser mit 0 verglichen werden kann. Die Umwandlung liefert den Wert 0, wenn failbit oder badbit im Fehlerstatus gesetzt sind. Im anderen Fall wird ein Zeigerwert zurückgegeben, der aber nicht verwendet werden sollte. Hierdurch können Ausdrücke in folgender Form eingesetzt werden:
Der Operator ! liefert - bei gesetztem badbit oder failbit im Fehlerstatus - einen Wertungleich 0, wodurch Ausdrücke wie der folgende verwendet werden können:
FormatierungEin ios-Objekt weist einen Formatstatus auf, der von Ein- und Ausgabeoperationen zur Steuerung der Details für die Formatierungsoperationen verwendet wird. Die Komponenten des Status können vom Programmcode des Benutzers gesetzt und nach Belieben untersucht werden. Die meisten Formatierungsdetails werden durch die Funktionen flags(), setf() und unsetf() mittels Setzen der folgenden Flags gesteuert, die in einer Aufzählung der Klasse ios deklariert sind. Drei weitere Komponenten des Formatstatus werden durch die Funktionen fill(), width() und precision() festgelegt. skipws Wenn skipws gesetzt ist, wird Zwischenraum in der Eingabe übersprungen. Dies bezieht sich auf skalare Extraktionen. left Durch diese Flags wird das Auffüllen eines Wertes festgelegt. Wenn left gesetzt ist,wird der Wert linksbündig ausgerichtet, so dass Füllzeichen hinter dem Wert angefügtwerden. Bei gesetztem right wird der Wert rechtsbündig ausgerichtet, und Füllzeichenwerden vor dem Wert eingefügt. Die Verwendung von internal führt dazu, dass Füllzeichen zwar hinter einem führenden Vorzeichen oder einer Basisindikation, aber nochvor dem Wert eingefügt werden. Die rechtsbündige Ausrichtung ist die Standardvorgabe, wenn kein Flag gesetzt ist. Die Felder werden gemeinsam durch das static-Element ios::adjustfield identifiziert. Die Funktion fill() legt das Füllzeichen fest. Die Breite, bis zu der aufgefüllt wird, wird durch die Funktion width() definiert. dec Diese Flags legen die Konvertierungsbasis eines Ganzzahlwertes fest. Die Konvertierungsbasis ist 10 (dezimal), wenn dec gesetzt ist. Sind hingegen oct oder hex gesetzt,so werden Umwandlungen im oktalen bzw. hexadezimalen System vorgenommen. Ist keines der drei Flags gesetzt, erfolgen Einfügungen dezimal, während Extraktionen entsprechend den lexikalischen Konventionen für Ganzzahlkonstanten in C++ interpretiert werden. Diese Felder werden gemeinsam durch das static-Element ios::basefield identifiziert. Die Manipulatoren hex, dec und oct können auch zum Setzen der Konvertierungsbasis verwendet werden (siehe "Vordefinierte Manipulatoren" in diesem Abschnitt). showbase Wenn showbase gesetzt ist, werden Einfügungen in eine externe Form umgewandelt,die entsprechend den lexikalischen Konventionen für Ganzzahlkonstanten in C++gelesen werden kann. Dies bedeutet, daß vor Oktalzahlen das Zeichen ’0’ erscheint,während Hexadezimalzahlen die Zeichenfolge ’0x’ (vgl. uppercase) vorangeht. Standardmäßig ist showbase nicht gesetzt. showpos Bei gesetztem showpos wird bei der dezimalen Umwandlung eines positiven Ganzzahlwertes ein Pluszeichen ’+’ eingefügt. uppercase Wenn uppercase gesetzt ist, wird der Großbuchstabe X für hexadezimale Ausgaben bei gesetztem showbase verwendet. Der Großbuchstabe E wird eingesetzt, um Gleitkommazahlen in der wissenschaftlichen Notation auszugeben. showpoint Im Ergebnis einer Gleitkomma-Umwandlung erscheinen Nullen und Dezimalpunkte am Ende der Zahlenangabe, wenn showpoint gesetzt ist. scientific Diese Flags legen das Format fest, in das ein Gleitkommawert zur Einfügung in einen Datenstrom umgewandelt wird.
scientific und fixed werden gemeinsam durch das static-Element ios::floatfield ausgedrückt. unitbuf Bei gesetztem unitbuf wird der Puffer durch ostream::osfx() nach jeder Einfügung"geleert". Die Einheitenpufferung stellt einen Kompromiss zwischen der gepufferten und der nicht gepufferten Ausgabe dar. Die Performance ist bei der Einheitenpufferung besser als ohne jede Pufferung, da im letztgenannten Fall für jedes ausgegebene Zeichen ein C-Laufzeitsystem-Aufruf ausgeführt wird. Die Einheitenpufferung führt nur bei jeder Einfügeoperation zu einem C-Laufzeitsystem-Aufruf, und der Benutzer muss ostream::flush() nicht aufrufen. Im BS2000 wird durch den Aufruf von ostream::flush() der Satz abgeschlossen und ein neuer Satz begonnen. stdio Ist stdio gesetzt, so werden stdout und stderr nach jedem Einfügen durch ostream::osfx() "geleert". Das bedeutet im BS2000, dass die aktuelle Zeile (Satz) beendet wird und die nächste Ausgabe in eine neue Zeile (Satz) erfolgt. Die folgenden Funktionen setzen und verwenden die Formatflags und Variablen. char oc=s.fill(char c) Die Formatstatusvariable für das Füllzeichen wird auf c gesetzt und der vorherige Variablenwert geliefert. c wird als Füllzeichen verwendet, wenn dies notwendig ist(siehe width()). Das Standardfüllzeichen ist das Leerzeichen. Die Positionierung der Füllzeichen wird durch die Flags left, right und internal (siehe oben) festgelegt. Ein parametrisierter Manipulator, setfill, ist ebenfalls verfügbar, um das Füllzeichen zusetzen. Weitere Informationen finden Sie bei manip . Hinweis Das "Füllzeichen" hat keine Auswirkungen auf die Eingabe. char c=s.fill() Es wird die Formatstatusvariable für das Füllzeichen geliefert. long l=s.flags() Die aktuelle Formatflagangabe wird geliefert. long l=s.flags(long f) Alle Formatflags werden auf die in f spezifizierte Angabe zurückgesetzt, und die vorherigen Einstellungen werden geliefert. int oi=s.precision(int i) Die Formatstatusvariable für die Genauigkeit wird auf i gesetzt, und der zuvor darin enthaltene Werte wird geliefert. Diese Variable steuert die Anzahl signifikanter Stellen,die durch den Gleitkomma-Inserter eingefügt werden. Der Standardwert ist 6. Ein parametrisierter Manipulator, setprecision, ist ebenfalls zur Einstellung der Genauigkeit verfügbar. Weitere Informationen finden Sie bei manip . int i=s.precision() Es wird die Formatstatusvariable für die Genauigkeit geliefert. long l=s.setf(long b) In s werden die durch b markierten Formatflags gesetzt, und die Einstellungen vor der Änderung werden geliefert. Alle anderen Flags bleiben unverändert. Ein parametrisierter Manipulator, setiosflags, hat dieselbe Funktion. Weitere Informationen finden Sie bei manip . long l=s.setf(long b, long f) In s werden nur die Formatflags, die durch f spezifiziert werden, auf die in b angegebenen Werte zurückgesetzt. Die Einstellungen vor der Wertänderung werden geliefert.Die in f angegebenen Formatflags werden hierbei in s gelöscht und dann auf die in b spezifizierten Werte gesetzt. Um die Konvertierungsbasis von s auf hex zu setzen, kann folgende Zeile verwendet werden:
Hierdurch werden alle vorherigen Einstellungen auf oct oder dec gelöscht. ios::basefield gibt an, dass die Konvertierungsbasis-Bits verändert werden sollen, während ios::hex den neuen Wert spezifiziert. s.setf(0, f) löscht alle durch f spezifizierten Bits. Der parametrisierte Manipulator resetiosflags hat dieselbe Aufgabe (siehe manip). long l=s.unsetf(long b) Die in b gesetzten Bits werden in s gelöscht, und es wird die Einstellung vor der Änderung geliefert. int oi=s.width(int i) Die Formatvariable für die Feldbreite wird auf i gesetzt und der Wert vor der Änderung geliefert. Dies hat für Aus- und Eingabeströme unterschiedliche Bedeutungen:
Ein parametrisierter Manipulator (setw) ist verfügbar, der die Feldbreite setzt (siehe manip). int i=s.width() Die Formatvariable für die Feldbreite wird geliefert. Benutzerdefinierte FormatflagsBei der Ableitung von Klassen aus der Basisklasse ios stehen dem Benutzer mehrere Funktionen für zusätzlich benötigte Formatflags und Variablen zur Verfügung. Die beiden static-Elementfunktionen ios::xalloc und ios::bitalloc erlauben es, mehrere solcher Klassen ohne gegenseitige Interferenzen zu verwenden. long b=ios::bitalloc() Es wird ein long-Wert geliefert, in dem ein einziges Bit gesetzt ist, das zuvor nicht belegt war. Dies erlaubt dem Benutzer bei Bedarf die Anforderung zusätzlicher Flags.Eine solche Angabe kann als Argument an ios:setf() übergeben werden. int i=ios::xalloc() Ein zuvor nicht verwendeter Index in einem Feld aus Worten wird geliefert und kann als Formatstatusvariable für abgeleitete Klassen eingesetzt werden. long & l=s.iword(int i) Wenn i ein durch ios::xalloc belegter Index ist, liefert die Funktion iword() eine Referenz auf das i-te benutzerdefinierte Wort. void*& vp=s.pword(int i) Ist i ein durch ios::xalloc belegter Index, liefert pword() eine Referenz auf das i-te benutzerdefinierte Wort. pword() und iword() sind, abgesehen vom unterschiedlichen Typ des Rückgabewerts, gleich. Weitere Elementfunktionenstreambuf* sb=s.rdbuf() Es wird ein Zeiger auf das streambuf-Objekt geliefert, das beim Anlegen von s mit s verknüpft war. static void ios::sync_with_stdio() Hierdurch werden Probleme gelöst, die bei der gemeinsamen Verwendung von stdiound iostream auftreten. Beim ersten Aufruf werden die Standard-iostream-Objekte (cin, cout, cerr und clog; siehe iosintro ) auf Datenströme zurückgesetzt, die stdiobuf-Objekte einsetzen. Hinweis Die Einheitenpufferung für Standard-Ein-/Ausgabe-Dateien im BS2000 bewirkt, dass jede gelesene-/geschriebene Einheit den aktuellen Satz schließt und das Lesen/Schreiben des nächsten Satzes gestartet wird. ostream * oosp=s.tie(ostream * osp) Die Verknüpfungsvariable wird auf osp gesetzt, und der Variablenwert vor der Änderung wird zurückgegeben. Die Variable unterstützt das automatische "Leeren" von ios-Objekten. Wenn die Verknüpfungsvariable ungleich 0 ist und ein ios-Objekt weitereZeichen erfordert oder Zeichen enthält, die "verbraucht" werden können, wird das ios-Objekt geleert, auf das die Verknüpfungsvariable zeigt. Standardmäßig ist cin anfänglich mit cout verknüpft, so dass der Versuch einer Entnahme weiterer Zeichen aus der Standardeingabe zum Leeren der Standardausgabe führt. Zusätzlich sind auch cerrund clog standardmäßig mit cout verknüpft. Für alle anderen ios-Objekte ist die Verknüpfungsvariable standardmäßig auf 0 gesetzt. ostream * osp=s.tie() Der Wert der Verknüpfungsvariable wird geliefert. Hinweis Im C-Laufzeitsystem werden vor dem Lesen von stdin (SYSDTA) Textausgabedateien entleert. iostream::tie beeinflußt die Übergabe des C++-Pufferinhaltes an das C-Laufzeitsystem. Die Übertragung aller Informationen aus dem C-Laufzeitsystem-Puffer indie Datei erfolgt unabhängig von dem Wert der tie-Variablen. Vordefinierte ManipulatorenEinige recht komfortable Manipulatoren (das sind Funktionen, die ein Objekt in der Form ios&, istream& oder ostream& übernehmen und ihr Argument zurückgeben, siehe manip) sind im folgenden aufgelistet: sr<<dec Hierdurch wird das Konvertierungsbasisflag in der Formatangabe auf 10 gesetzt. sr<<hex Hierdurch wird das Konvertierungsbasisflag in der Formatangabe auf 16 gesetzt. sr<<oct Hierdurch wird das Konvertierungsbasisflag in der Formatangabe auf 8 gesetzt. sr>>ws Zwischenraumzeichen werden extrahiert (siehe istream ). sr<<endl Eine Zeile wird beendet, indem ein Neue-Zeile-Zeichen eingefügt und der Puffer geleert wird (siehe ostream ). sr<<ends Eine Zeichenkette wird beendet, indem ein Nullzeichen (0) angehängt wird (siehe ostream). sr<<flush sr wird geleert (siehe ostream ). In manip werden parametrisierte Manipulatoren beschrieben, die auf ios-Objekte angewendet werden: setbase, setw, setfill, setprecision, setiosflags und resetiosflags. Das mit einem ios-Objekt assoziierte streambuf-Objekt kann auch durch andere Methoden als über das ios-Objekt manipuliert werden. So können Zeichen in einem Warteschlangen-ähnlichen streambuf-Objekt durch ein ostream-Objekt gespeichert und durch ein istream-Objekt entnommen werden. Aus Effizienzgründen kann ein Teil des Programmes auch direkt die streambuf-Operationen ansprechen, statt den "Umweg" über ios zuwählen. In den meisten Fällen muss sich ein Programm aber nicht mit dieser Möglichkeit beschäftigen, da ein ios-Objekt keine Informationen zum internen Status des streambuf-Objektes enthält. Wenn das streambuf-Objekt zwischen zwei Extraktionsoperationen neu positioniert wird, kann die Extraktion (Eingabe) anschließend normal fortgeführt werden. | |||||||||
BEISPIEL | Das folgende Programm setzt einige Datenelemente der Klasse ios ein, um das Ausgabeformat von Ganz- und double-Zahlen in cout zu ändern: #include <iostream.h> #include <math.h> void someoutput() { int i; const int N = 12; for (i = 1; i < N; i += 2) { cout << "\t" << i << " " << pow( (double) i, (double) i) << endl; } cout << "\n"; } int main() { cout << "Standardformat :\n"; someoutput(); /* Standardformate für Ganzzahlen und double-Wert anzeigen */ cout.setf( ios::fixed, ios::floatfield); /* Ausgabeformate für float- und double-Werte auf fixed setzen*/ cout << "float- bzw. double-Werte werden nun mit fixed ausgegeben :\n"; someoutput(); cout.setf( ios::oct, ios::basefield); /* Ausgabeformat für Ganzzahlen auf octal setzen */ cout << "Ganzzahlen werden nun oktal ausgegeben :\n"; someoutput(); return 0; } Das Ergebnis der Programmausführung ist: Standardformat : 1 1 3 27 5 3125 7 823543 9 3.8742e+08 11 2.85312e+11 float- bzw. double-Werte werden nun mit fixed ausgegeben : 1 1.000000 3 27.000000 5 3125.000000 7 823543.000000 9 387420488.999998 11 285311670610.995117 Ganzzahlen werden nun oktal ausgegeben : 1 1.000000 3 27.000000 5 3125.000000 7 823543.000000 11 387420488.999998 13 285311670610.995117 % CCM0998 Verbrauchte CPU-Zeit: 0.0066 Sekunden Hinweis Die Genauigkeit dieser Resultate hängt vom verwendeten Rechner ab. | ||||||||
BESONDERHEITEN | |||||||||
Das Kopieren von Datenströmen ist im iostream-Paket nicht möglich. An Objekte der Typen istream_withassign, ostream_withassign und iostream_withassign können aber Zuweisungen erfolgen. (Die Standardströme cin, cout, cerr und clog sind Elemente der"withassign"-Klassen, so daß Zuweisungen - wie bei cin=inputfstream - ausgeführt werden können.) | |||||||||
SIEHE AUCH | |||||||||