Stream-Formatierung mit I / O-Manipulatoren

Eine der Schwierigkeiten mit C ++ in bewegten Objekten zur Ausgabe an Strom wird zu lernen, wie die Ausgabe zu formatieren. Tatsächlich gibt es zwei Möglichkeiten zur Formatierung-Stream-I / O.

Die erste Technik, die Programmierer normalerweise durch direkte Methodenaufrufe lernen. Zum Beispiel setzt der folgende Aufruf den Ausgangsstrom in Hexadezimal-Modus, so dass ganze Zahlen als Hexadezimalwerte Bildschirm angezeigt werden und nicht als Dezimal-Werte:

ios :: fmtflags prev = cout.setf (ios :: hex, ios :: FIELD) -

hier ist die setf () Methode legt das Format-Flags, indem zuerst die Bits im zweiten Argument Abkleben und dann die Bits durch das erste Argument angegeben Einstellung. Die Funktion gibt den alten Wert, so dass die anrufende Funktion, um die Format-Flags vor der Rückkehr wiederherstellen.

In der Praxis wird diese Funktion wie folgt:

#einschließen using namespace std - // displayHex - eine Zahl in Hex-Anzeige formatvoid displayHex (Ostream out, int n) {ios :: fmtflags prev = out.setf (ios :: hex, ios :: FIELD) -out lt; lt; n-out.setf (i) -} int main () {int n = 0x1234-cout lt; lt; "N =" lt; lt; n lt; lt; Endl-cout lt; lt; "N in hex" -displayHex (cout, n) -cout lt; lt; Endl-return 0-}

Das Programm beginnt mit der variablen Einstellung n in einen hexadezimalen Wert. Es zeigt dann den Wert cout. Er ruft dann die displayHex () Funktion den Wert hexadezimal angezeigt werden soll. Die Ausgabe von dem Programm erscheint, wie folgt:

n = 4660n in hex 1234

Der Wert im Dezimalformat ist nicht erkennbar, aber die hexadezimale Anzeige ist eindeutig der Wert verwendet zu initialisieren n.

Allerdings gibt es in C ++ eine zweite Möglichkeit, E / A-Format zu steuern: I / O-Manipulatoren.

Was ist ein I / O-Manipulator?

Ein I / O-Manipulator das ist ein Ziel der Programmierer in den Ausgabestrom einfügen können die Formatsteuerfunktionen aufzurufen. Das folgende Codefragment zeigt den Benutzer von E / A-Manipulatoren. Es hat die gleiche Funktion wie der Stand der Schnipsel, außer diese Version eine I / O-Manipulator verwendet die aufzurufen setf () Funktion:

#einschließen #einschließen using namespace std-int main () {int n = 0x1234-cout lt; lt; "N =" lt; lt; n lt; lt; endllt; lt; "N in hex" lt; lt; setBase (16) lt; lt; n lt; lt; Endl-return 0-}

Hier Main() erste Ausgänge n als Dezimalwert. Es verwendet dann die setBase (16) Manipulator die Anzeige Basis von dezimal zu ändern (Basis 10) in hexadezimal (Basis 16), bevor er wieder den Wert anzuzeigen. Die Ausgabe dieser Version ist zu unterscheiden von der früheren Version:

n = 4660n in hex 1234

Das setBase (16) Objekt erscheint wie ein Aufruf einer Funktion in der Mitte des Ausgangsstroms. Die Tatsache, dass ein Objekt erzeugt wird, ist für den Benutzer unsichtbar.

Für hexadezimal, oktal und dezimal, bietet C ++ die Verknüpfungen verhexen, Oktober und Dezember was bedeutet, dass der Code die folgenden noch kürzere Form annehmen könnte:

cout lt; lt; "N =" lt; lt; n lt; lt; endllt; lt; "N in hex" lt; lt; verhexen lt; lt; n lt; lt; endl-

Was I / O-Manipulatoren nicht C ++ anbieten?

Werfen Sie einen Blick auf diese Tabelle, die eine Liste von E / A-Manipulatoren zur Verfügung C ++ 2011 enthält.

Allgemeine E / A-Manipulatoren
I / O ManipulatorFunktion
boolalpha
noboolalpha
Zum Umschalten zwischen Text- und numerischen Anzeige eines Booleschen. Wannboolalpha gesetzt ist, wahr und falsch appearonscreen als 'wahr' und 'falsch'. Wenn es nicht gesetzt ist, erscheinen sie als '1'Und' 0 '.
showbase
noshowbase
Wann showbase gesetzt ist, Oktal valuesare durch ein voran 0 und hexadecimalvalues ​​vorangestellt '0x' oder '0X'.
showpoint
noshowpoint
Ein Dezimalpunkt wird immer dann angezeigt, wenn showpoint gesetzt.
showpos
noshowpos
zeigt ein '+' Zeichen vor ofpositive Werte, wenn showpos set.Displays ist nichts, wenn noshowpos isset.
skipws
noskipws
Springt Leerraum auf Eingabe.
Groß
nouppercase
Ob Groß gesetzt ist, dann useuppercase für Ausgabeformate, zum Beispiel '0X'Für hexadezimale Ausgabe. Wenn nouppercase gesetzt ist, verwenden Klein, zum Beispiel,'0x'Für hexadezimale Ausgabe.
unitbuf
nounitbuf
Wenn gesetzt, dann wird die Ausgabe nicht gepuffert aber nach eachinsert gespült. Wenn nicht gesetzt, wird die Ausgabe gepuffert.
fest
wissenschaftlich
Set Ausgabe von Fließkommawerte entweder fest orscientific Notation.
wsDieses Objekt isst weißen Raum von einem Eingangsstrom.
EndenFügt ein Null-Zeichen (' 0') In einen Outputstream. Nützlich für die abschließende Null eine Zeichenfolge, wenn ostrstream verwenden.
spülenLeert alle Puffer Zeichen in den Ausgabestream.
endlFügt ein Newline-Zeichen.
setiosflags(N)
resetiosflags(N)
Set oder deaktivieren Sie das ios Fahnen enmasse.
setBase (n)Legt die Basis für Integer-Eingang und Ausgang bis 8, 10, 16 oder 0.See Text zur Erklärung von 0.
Dezember

Oktober
verhexen
Stellen Sie die Basis auf dezimal, oktal oder hexadezimal.
Stenografie für setBase (10), setBase (8) und setBase (16), respectively.
setfill (c)Legt das Zeichen Raum zu füllen, wenn die Zahl anzuzeigen ofcharacters kleiner als die Feldbreite. Der defaultcharacter ist ein Raum.
setprecision (n)Legt die Anzahl der Stellen ausgegeben werden, wenn afloating Punktzahl angezeigt wird.
setw (n)Legt die minimale Breite des nächsten Ausgabefeld. Das Feld IsExpanded mit setfill () Zeichen wie nötig.
setfill (c)Legt das Zeichen Raum zu füllen, wenn die Zahl anzuzeigen ofcharacters kleiner als die Feldbreite. Der defaultcharacter ist ein Raum.


intern
links
Recht
Stellen Sie die Platzierung von Füllzeichen. Wenn die Füllung characterwere '*' (zum Beispiel), dann gilt:
intern -"$ ** 123,00"
links - "** 123,00 $"
Recht - "123,00 $ **"
Geld bekommen()
put_money ()
Lesen oder einen monetären Wert anzuzeigen, die lokalen Regeln als setby locale verwenden. (Dies ist nicht in der aktuellen Version ofgcc implementiert.)
Zeit bekommen()
put_time ()
Lesen Sie oder eine Uhrzeit oder das Datum angezeigt werden, die örtlichen Regeln als Set bylocale verwenden. (Dies ist nicht in der aktuellen Version ofgcc implementiert.)

Die meisten der Manipulatoren sind unkompliziert. Einige verlangen eine Erklärung, aber. Zum Beispiel in Bezug auf die setBase () Manipulator, nicht alle Werte von Basis werden unterstützt. In der Tat unterstützt C ++ nur dezimal, oktal und hexadezimal I / O - was in Ordnung ist, wie das ist alles ziemlich viel, was erforderlich ist. Sie können jedoch die Möglichkeit, die Basis zu 0 - in der Tat, 0 ist der Standardwert.

Basis Einstellung auf 0 ist das gleiche wie das Einstellen für die Ausgabe in Dezimalzahlen. Für die Eingabe jedoch bedeutet die Basis auf 0 setzen "extrahieren Sie die Base aus der Zahl selbst". Die Regeln dafür sind so, wie folgt:

  • # 42 Wenn eine Zahl mit 0x oder 0X beginnt, wird angenommen, hexadezimal sein.

  • # 42-Wenn eine Zahl mit nur 0 beginnt, dann wird angenommen, oktale sein.

  • # 42-ansonsten wird die Zahl sein dezimal angenommen.

Das folgende einfache Programm zeigt diese Regeln:

#einschließen #einschließen using namespace std-int main () {int n1, n2, n3-cin >> setBase (0) >> n1 >> n2 >> n3-cout lt; lt; showbase lt; lt; setBase (16) lt; lt; "N1 =" lt; lt; n1 lt; lt; ", N2 =" lt; lt; n2lt; lt; ", N3 =" lt; lt; n3 lt; lt; Endl-return 0-}

Die erste Zeile stellt die Basis für die cin Objekt auf 0 gesetzt und extrahiert dann drei ganze Zahlen. Die zweite Zeile zeigt diese drei ganze Zahlen in Hexadezimal-Format. Das showbase Manipulator bewirkt, dass die führende '0x' angezeigt für hexadezimale Werte. Das folgende Beispiel zeigt die Durchführung dieses Programms, in dem die drei Zahlen in fett sind Werte, die ich von der Tastatur eingegeben:

10 010 0x10n1 = 0xa, n2 = 0x8, n3 0x10 =

Sie können sehen, dass die erste Zahl als 10 in der Basis interpretiert wurde 10, die 0xA in hexadezimal ist. Die zweite Zahl wurde als 10 in der Basis 8, interpretiert die 8 in hexadezimal ist. Die dritte und letzte Zahl wurde als 10 in hexadezimaler interpretiert.

Ein weiterer Manipulator, der besondere Erwähnung verdient, ist die setw (), Abkürzung für "set Breite". Dies legt die minimale Breite des nächsten Feld angezeigt. Das folgende einfache Programm zeigt, wie setw ()interagiert mit Polsterung und dem Füllzeichen:

#einschließen #einschließen using namespace std-int main () {int width-int-Wert-cout lt; lt; "Geben Sie die Breite:" - cin >> Breite-cout lt; lt; setfill ( '*') - für (-) {cout lt; lt; "Geben Sie einen Wert:" - cin >> Wert-if (value == 0) {Break-} cout lt; lt; "Links, Rechts und intern: n" lt; lt; links lt; lt; setw (Breite) lt; lt; Wert lt; lt; "," Lt; lt; rightlt; lt; setw (Breite) lt; lt; Wert lt; lt; "," Lt; lt; intern lt; lt; setw (Breite) lt; lt; Wert lt; lt; endl-} return 0-}

Dieses Programm setzt den Füllzeichen zu '*' (Der Standard ist Raum). Sie liest dann die Breite für alle Zahlen von der Tastatur verwendet werden, bevor eine Schleife eintritt, der liest und zeigt Werte. Innerhalb dieser Schleife zeigt das Programm zunächst die Zahl mit links, Hand füllen, dann mit rechts, Handfüllung und schließlich mit Innenfüllung.

Im Folgenden ist ein Probelauf des Programms mit dem Eingang bolded:

Geben Sie die Breite:5Geben Sie einen Wert:100000Links, Rechts und intern: 100000, 100000, 100000Enter ein Wert:100Links, Rechts und intern: 100 **, ** 100, ** 100Enter ein Wert:-100Links, Rechts und intern: -100 *, * -100, - * 100Enter ein Wert:0

Hier 5 ist als die Breite des Feldes eingegeben werden. Allerdings trat der erste Wert, 100.000, erfordert mehr als 5 Spalten angezeigt werden so keine der Anzeigefelder keine Wirkung hatte. Die eingestellte Breite setzt nur die minimale Breite anzuzeigen.

Der nächste Wert eingegeben, 100, erfordert nur drei Spalten angezeigt werden, so dass das Programm angezeigt, um den Wert zunächst mit zwei * Zeichen auf der rechten Seite, dann auf der linken Seite, und wieder auf der linken Seite.

Der nächste Wert eingegeben, -100, demonstriert den Unterschied zwischen richtig füllen und interne Füllung. Rechts Füllung setzen die Füllzeichen auf der linken Seite des Wertes, einschließlich dem Minuszeichen. Interne Füllung setzen die Füllzeichen zwischen dem Wert und dem Minuszeichen. Dies funktioniert auch bei einem Pluszeichen, wenn plus ist mit der gezwungen showpos Manipulator und zwischen der Zahl und dem Währungszeichen (wenn Währung vom Compiler unterstützt wird).

Die Manipulatoren füge keine Fähigkeit, die nicht bereits vorhanden ist. Immerhin endet jeder dieser Manipulatoren eine öffentliche Methode auf dem Stream-Objekt aufrufen. Sie weisen jedoch ein bequemes Mittel des I / O Formatierung.

Menü