Använda infogningsoperatorer och kontrollera format
Det här avsnittet visar hur du styr format och hur du skapar infogningsoperatorer för dina egna klasser. Operatorn insertion (<<
) som är förprogrammerad för alla C++-standarddatatyper skickar byte till ett utdataströmobjekt. Infogningsoperatorer fungerar med fördefinierade "manipulatorer", som är element som ändrar standardformatet för heltalsargument.
Du kan styra formatet med följande alternativ:
Utdatabredd
Om du vill justera utdata anger du utdatabredden för varje objekt genom att placera setw
manipulatorn i strömmen eller genom att anropa funktionen width
medlem. I det här exemplet justeras värdena i en kolumn med minst 10 tecken breda:
// 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
Inledande tomma värden läggs till i ett värde som är mindre än 10 tecken brett.
Om du vill fylla på ett fält använder du funktionen fill
medlem, som anger värdet för utfyllnadstecknet för fält som har en angiven bredd. Standardvärdet är tomt. Om du vill fylla kolumnen med tal med asterisker ändrar du föregående for
-loop enligt följande:
for (int i = 0; i <4; i++)
{
cout.width(10);
cout.fill('*');
cout << values[i] << endl;
}
Den endl
manipulatorn ersätter det nya tecknet ('\n'
). Utdata ser ut så här:
******1.23
*****35.36
*****653.7
***4358.24
Om du vill ange bredd för dataelement på samma rad använder du setw
manipulatorn:
// 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;
}
Funktionen width
medlem deklareras i <iostream>
. Om du använder setw
eller någon annan manipulator med argument måste du inkludera <iomanip>
. I utdata skriver strängar ut i ett fält med bredd 7 och heltal i ett fält med bredd 10:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
setw
och width
trunkerar inte värden. Om formaterade utdata överskrider bredden skrivs hela värdet ut, beroende på strömmens precisionsinställning. Både setw
och width
endast påverka följande fält. Fältbredden återgår till standardbeteendet (den nödvändiga bredden) när ett fält har skrivits ut. De andra alternativen för strömformat gäller dock tills de har ändrats.
Justering
Utdataströmmar är som standard högerjusterad text. Om du vill vänsterjustera namnen i föregående exempel och högerjustera talen ersätter du for
-loopen på följande sätt:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6) << names[i]
<< resetiosflags(ios::left)
<< setw(10) << values[i] << endl;
Utdata ser ut så här:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
Flaggan vänsterjusteras med hjälp av setiosflags
manipulator med left
uppräknaren. Den här uppräknaren definieras i klassen ios
, så dess referens måste innehålla ios::
prefix. Den resetiosflags
manipulatorn inaktiverar vänsterjustera flaggan. Till skillnad från width
och setw
är effekten av setiosflags
och resetiosflags
permanent.
Precision
Standardvärdet för flyttalsprecision är sex. Till exempel skrivs talet 3466.9768 ut som 3466,98. Om du vill ändra hur det här värdet skrivs ut använder du setprecision
manipulatorn. Manipulatorn har två flaggor: fixed
och scientific
. Om fixed
anges skrivs talet ut som 3466.976800. Om scientific
anges skrivs den ut som 3.4669773+003.
Om du vill visa flyttalsnumren som visas i Justering med en betydande siffra ersätter du for
-loopen på följande sätt:
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;
Den här listan skrivs ut:
Zoot 1
Jimmy 4e+01
Al 7e+02
Stan 4e+03
Om du vill eliminera vetenskaplig notation infogar du den här instruktionen före for
-loopen:
cout << setiosflags(ios::fixed);
Med fast notation skrivs programmet ut med en siffra efter decimaltecknet.
Zoot 1.2
Jimmy 35.4
Al 653.7
Stan 4358.2
Om du ändrar flaggan ios::fixed
till ios::scientific
skriver programmet ut följande:
Zoot 1.2e+00
Jimmy 3.5e+01
Al 6.5e+02
Stan 4.4e+03
Återigen skriver programmet ut en siffra efter decimaltecknet. Om antingen ios::fixed
eller ios::scientific
anges avgör precisionsvärdet antalet siffror efter decimaltecknet. Om ingen av flaggorna anges avgör precisionsvärdet det totala antalet signifikanta siffror. Den resetiosflags
manipulatorn rensar dessa flaggor.
Radix
dec
, oct
och hex
manipulatorer anger standardradixet för indata och utdata. Om du till exempel infogar hex
manipulator i utdataströmmen översätter objektet korrekt den interna datarepresentationen av heltal till ett hexadecimalt utdataformat. Talen visas med siffror a till och med f i gemener om flaggan uppercase
är klar (standardvärdet); annars visas de i versaler. Standardradixet är dec
(decimal).
Citerade strängar (C++14)
När du infogar en sträng i en ström kan du enkelt hämta samma sträng genom att anropa funktionen stringstream::str()
medlem. Men om du vill använda extraheringsoperatorn för att infoga strömmen i en ny sträng vid ett senare tillfälle kan du få ett oväntat resultat eftersom >>
operatorn som standard stoppas när den hittar det första blankstegstecknet.
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
Det här beteendet kan övervinnas manuellt, men för att göra strängen rund-tripping bekvämare lägger C++14 till std::quoted
strömmanipulatör i <iomanip>
. Vid infogning omger quoted()
strängen med en avgränsare (dubbla citattecken som standard) och vid extrahering manipuleras strömmen för att extrahera alla tecken tills den slutliga avgränsaren hittas. Inbäddade citattecken är undantagna med ett escape-tecken ('\\' som standard).
Avgränsarna finns bara i strömobjektet. de finns inte i den extraherade strängen, men de finns i strängen som returneras av basic_stringstream::str
.
Beteendet för blanksteg för infognings- och extraheringsåtgärder är oberoende av hur en sträng representeras i kod, så den citerade operatorn är användbar oavsett om indatasträngen är en rå strängliteral eller en vanlig sträng. Indatasträngen, oavsett format, kan ha inbäddade citattecken, radbrytningar, flikar och så vidare, och alla dessa bevaras av quoted()
manipulator.
Mer information och fullständiga kodexempel finns i quoted
.