Verwenden von Einfügeoperatoren und Festlegen des Formats
In diesem Thema wird veranschaulicht, wie Sie das Format steuern und Einfügeoperatoren für Ihre eigenen Klassen erstellen. Der Einfügeoperator (<<
), der für alle standardmäßigen C++-Datentypen vorprogrammiert ist, sendet Bytes an ein Ausgabestreamobjekt. Einfügeoperatoren arbeiten mit vordefinierten „Manipulatoren“, d. h. Elementen, die das Standardformat von Ganzzahlargumenten ändern.
Sie können das Format mit den folgenden Optionen steuern:
Breite der Ausgabe
Zum Ausrichten der Ausgabe geben Sie die Ausgabebreite für jedes Element an, indem Sie den setw
Manipulator im Datenstrom platzieren oder die width
Memberfunktion aufrufen. In diesem Beispiel werden die Werte in einer Spalte mit einer Breite von mindestens 10 Zeichen rechtsbündig ausgerichtet:
// output_width.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
int main( )
{
double values[] = { 1.23, 35.36, 653.7, 4358.24 };
for( int i = 0; i < 4; i++ )
{
cout.width(10);
cout << values[i] << '\n';
}
}
1.23
35.36
653.7
4358.24
Führende Leerzeichen werden Werten mit einer Breite von weniger als 10 Zeichen hinzugefügt.
Verwenden Sie zum Auffüllen eines Felds die fill
Memberfunktion, die den Wert des Abstandszeichens für Felder mit einer angegebenen Breite festlegt. Der Standardwert ist leer. Um die Spalte der Zahlen mit Sternchen zu beschriften, ändern Sie die vorherige for
Schleife wie folgt:
for (int i = 0; i <4; i++)
{
cout.width(10);
cout.fill('*');
cout << values[i] << endl;
}
Der endl
-Manipulator ersetzt das Zeilenvorschubzeichen ('\n'
). Die Ausgabe sieht wie folgt aus:
******1.23
*****35.36
*****653.7
***4358.24
Verwenden Sie zum Angeben der Breite für Datenelemente in der gleichen Zeile den setw
-Manipulator:
// setw.cpp
// compile with: /EHsc
#include <iostream>
#include <iomanip>
using namespace std;
int main( )
{
double values[] = { 1.23, 35.36, 653.7, 4358.24 };
const char *names[] = { "Zoot", "Jimmy", "Al", "Stan" };
for( int i = 0; i < 4; i++ )
cout << setw( 7 ) << names[i]
<< setw( 10 ) << values[i] << endl;
}
Die width
Memberfunktion wird in <iostream>
deklariert. Wenn Sie einen anderen Manipulator mit Argumenten verwenden setw
, müssen Sie diese einschließen <iomanip>
. In der Ausgabe werden Zeichenfolgen in einem Feld der Breite 7 und ganze Zahlen in einem Feld der Breite 10 gedruckt:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
setw
und width
nicht abgeschnittene Werte. Wenn eine formatierte Ausgabe die Breite überschreitet, wird je nach der Einstellung der Genauigkeit des Streams der gesamte Wert ausgegeben. Beides setw
und width
wirken sich nur auf das folgende Feld aus. Die Feldbreite wird auf das Standardverhalten (die erforderliche Breite) zurückgesetzt, nachdem ein Feld ausgegeben wurde. Jedoch behalten die anderen Streamformatoptionen ihre Gültigkeit, bis sie geändert werden.
Ausrichtung
Ausgabestreams werden standardmäßig als rechtsbündiger Text ausgegeben. Wenn Sie die Namen im vorherigen Beispiel linksbündig ausrichten und die Zahlen rechtsbündig ausrichten möchten, ersetzen Sie die for
Schleife wie folgt:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6) << names[i]
<< resetiosflags(ios::left)
<< setw(10) << values[i] << endl;
Die Ausgabe sieht wie folgt aus:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
Das Kennzeichen linksbündig wird mithilfe des setiosflags
Manipulators mit dem left
Enumerator festgelegt. Dieser Enumerator wird in der ios
Klasse definiert, sodass sein Verweis das ios::
Präfix enthalten muss. Der resetiosflags
Manipulator deaktiviert die linksbündige Kennzeichnung. Im Gegensatz width
zu und , ist die Wirkung von setw
und setiosflags
resetiosflags
ist dauerhaft.
Präzision
Der Standardwert für die Gleitkommagenauigkeit ist sechs. Beispielsweise wird die Zahl 3466.9768 als 3466.98 gedruckt. Verwenden Sie den setprecision
Manipulator, um die Art und Weise zu ändern, wie dieser Wert gedruckt wird. Der Manipulator weist zwei Flags auf: fixed
und scientific
. Wenn fixed
festgelegt, wird die Zahl als 3466.976800 gedruckt. Wenn scientific
festgelegt, wird sie als 3.4669773+003 gedruckt.
Um die gleitkommazahlen anzuzeigen, die in der Ausrichtung mit einer signifikanten Ziffer angezeigt werden, ersetzen Sie die for
Schleife wie folgt:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6)
<< names[i]
<< resetiosflags(ios::left)
<< setw(10)
<< setprecision(1)
<< values[i]
<< endl;
Das Programm gibt diese Liste aus:
Zoot 1
Jimmy 4e+01
Al 7e+02
Stan 4e+03
Um die wissenschaftliche Schreibweise zu beseitigen, fügen Sie diese Anweisung vor der for
Schleife ein:
cout << setiosflags(ios::fixed);
Bei fester Schreibweise gibt das Programm mit einer Ziffer nach dem Dezimaltrennzeichen aus.
Zoot 1.2
Jimmy 35.4
Al 653.7
Stan 4358.2
Wenn Sie die ios::fixed
Kennzeichnung ios::scientific
ändern, druckt das Programm Folgendes:
Zoot 1.2e+00
Jimmy 3.5e+01
Al 6.5e+02
Stan 4.4e+03
Auch hier gibt das Programm mit einer Ziffer nach dem Dezimaltrennzeichen aus. Wenn eine oder ios::fixed
mehrere ios::scientific
Werte festgelegt sind, bestimmt der Genauigkeitswert die Anzahl der Ziffern nach dem Dezimalkomma. Wenn keines der beiden Flags festgelegt ist, bestimmt der Wert für die Genauigkeit die Gesamtzahl der signifikanten Stellen. Der resetiosflags
-Manipulator deaktiviert diese Flags.
Basis
Die dec
, oct
und hex
die Manipulatoren legen den Standardradiix für Eingabe und Ausgabe fest. Wenn Sie beispielsweise den hex
Manipulator in den Ausgabedatenstrom einfügen, übersetzt das Objekt die interne Datendarstellung von ganzzahligen Zahlen korrekt in ein Hexadezimalausgabeformat. Die Zahlen werden in Kleinbuchstaben mit Ziffern a bis f angezeigt, wenn die uppercase
Kennzeichnung deaktiviert ist (Standardeinstellung). Andernfalls werden sie in Großbuchstaben angezeigt. Der Standardradiix ist dec
(dezimal).
Zeichenfolge in Anführungszeichen (C++14)
Wenn Sie eine Zeichenfolge in einen Datenstrom einfügen, können Sie dieselbe Zeichenfolge ganz einfach wieder abrufen, indem Sie die stringstream::str()
Memberfunktion aufrufen. Wenn Sie jedoch den Extraktionsoperator verwenden möchten, um den Datenstrom zu einem späteren Zeitpunkt in eine neue Zeichenfolge einzufügen, wird möglicherweise ein unerwartetes Ergebnis angezeigt, da der >>
Operator standardmäßig beendet wird, wenn es das erste Leerzeichen findet.
std::stringstream ss;
std::string inserted = "This is a sentence.";
std::string extracted;
ss << inserted;
ss >> extracted;
std::cout << inserted; // This is a sentence.
std::cout << extracted; // This
Dieses Verhalten können Sie manuell umgehen, um Zeichenfolgen-Roundtrips aber praktischer zu gestalten, fügt C++ 14 den std::quoted
-Streammanipulator in <iomanip>
ein. Wenn Sie die Zeichenfolge einfügen, wird die Zeichenfolge durch ein Trennzeichen (standardmäßig doppeltes Anführungszeichen " ' ) umgeben, und bei der Extraktion wird der Datenstrom so geändert, quoted()
dass alle Zeichen extrahiert werden, bis das endgültige Trennzeichen gefunden wird. Alle eingebetteten Anführungszeichen werden mit einem Escapezeichen ('\\' standardmäßig) escapezeichen.
Die Trennzeichen sind nur im Streamobjekt vorhanden; sie sind nicht in der extrahierten Zeichenfolge vorhanden, sind aber in der von basic_stringstream::str
ihnen zurückgegebenen Zeichenfolge vorhanden.
Das Leerzeichenverhalten der Einfüge- und Extraktionsvorgänge ist unabhängig von der Art der Darstellung einer Zeichenfolge im Code, sodass der in Anführungszeichen gesetzte Operator unabhängig davon nützlich ist, ob die Eingabezeichenfolge ein unformatiertes Zeichenfolgenliteral oder eine reguläre Zeichenfolge ist. Die Eingabezeichenfolge, unabhängig vom Format, kann eingebettete Anführungszeichen, Zeilenumbrüche, Registerkarten usw. enthalten, und all diese werden vom quoted()
Manipulator beibehalten.
Weitere Informationen und vollständige Codebeispiele finden Sie unter quoted
.