Dela via


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::scientificskriver 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, octoch 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.

Se även

utdataströmmar