Beszúrási operátorok és vezérlőformátum használata

Ez a témakör bemutatja, hogyan szabályozhatja a formátumot, és hogyan hozhat létre beszúrási operátorokat saját osztályokhoz. A beszúrási (<<) operátor, amely minden szabványos C++ adattípushoz előre van programozva, bájtokat küld egy kimeneti streamobjektumnak. A beszúrási operátorok előre definiált "manipulátorokkal" dolgoznak, amelyek az egész szám argumentumainak alapértelmezett formátumát módosító elemek.

A formátumot a következő beállításokkal szabályozhatja:

Kimeneti szélesség

A kimenet igazításához adja meg az egyes elemek kimeneti szélességét úgy, hogy a setw manipulátort a streambe helyezi, vagy meghívja a width tagfüggvényt. Ez a példa egy legalább 10 karakter széles oszlop értékeit igazítja jobbra:

// 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

A kezdő üres karakterek 10 karakternél rövidebb értékhez lesznek hozzáadva.

Mező kitöltéséhez használja a fill tagfüggvényt, amely a megadott szélességű mezőkhöz állítja be a kitöltési karakter értékét. Az alapértelmezett érték egy üres. A számok oszlopának csillaggal való kitöltéséhez módosítsa az előző for hurkot az alábbiak szerint:

for (int i = 0; i <4; i++)
{
    cout.width(10);
    cout.fill('*');
    cout << values[i] << endl;
}

A endl manipulátor lecseréli az új vonal karaktert ('\n'). A kimenet a következőképpen néz ki:

******1.23
*****35.36
*****653.7
***4358.24

Ha az azonos sorban lévő adatelemek szélességét szeretné megadni, használja a setw manipulátort:

// 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;
}

A width tagfüggvény <iostream>deklarálva van. Ha argumentumokkal setw vagy bármely más manipulátort használ, <iomanip>kell tartalmaznia. A kimenetben a sztringek 7 szélességű mezőben, a 10 szélességű mezőben pedig egész számokat nyomtatnak:

   Zoot      1.23
  Jimmy     35.36
     Al     653.7
   Stan   4358.24

setw és width nem csonkítják az értékeket. Ha a formázott kimenet meghaladja a szélességet, a teljes érték a stream pontossági beállításának megfelelően jelenik meg. Mind setw, mind width csak a következő mezőre van hatással. A mezőszélesség egy mező kinyomtatása után visszaáll az alapértelmezett viselkedésére (a szükséges szélességre). A többi streamformátum-beállítás azonban a módosításig érvényben marad.

Igazítás

A kimeneti streamek alapértelmezés szerint jobbra igazított szövegre vannak igazítva. Az előző példában szereplő nevek balra igazításához és a számok jobbra igazításához cserélje le a for hurkot az alábbiak szerint:

for (int i = 0; i <4; i++)
    cout << setiosflags(ios::left)
         << setw(6) << names[i]
         << resetiosflags(ios::left)
         << setw(10) << values[i] << endl;

A kimenet a következőképpen néz ki:

Zoot        1.23
Jimmy      35.36
Al         653.7
Stan     4358.24

A bal oldali igazítás jelző a setiosflags manipulátor és a left enumerátor használatával van beállítva. Ez az enumerátor a ios osztályban van definiálva, ezért a hivatkozásnak tartalmaznia kell a ios:: előtagot. A resetiosflags manipulátor kikapcsolja a bal oldali igazítás jelzőt. A width és setwellentétben a setiosflags és a resetiosflags hatása állandó.

Precizitás

A lebegőpontos pontosság alapértelmezett értéke hat. A 3466.9768 szám például 3466,98-as. Az érték nyomtatási módjának módosításához használja a setprecision manipulátort. A manipulátor két jelölőt használ: fixed és scientific. Ha fixed van beállítva, a szám 3466,976800 lesz. Ha scientific be van állítva, az 3,4669773+003-as számként jelenik meg.

Ha az igazítási lebegőpontos számokat egy jelentős számjegyre szeretné megjeleníteni, cserélje le a for hurkot az alábbiak szerint:

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;

A program a következő listát nyomtatja:

Zoot          1
Jimmy     4e+01
Al        7e+02
Stan      4e+03

A tudományos jelölés megszüntetéséhez szúrja be ezt az utasítást a for hurok elé:

cout << setiosflags(ios::fixed);

Rögzített jelöléssel a program egy számjegyet nyomtat a tizedesvessző után.

Zoot         1.2
Jimmy       35.4
Al         653.7
Stan      4358.2

Ha a ios::fixed jelzőt ios::scientificjelölőre módosítja, a program a következőt nyomtatja ki:

Zoot    1.2e+00
Jimmy   3.5e+01
Al      6.5e+02
Stan    4.4e+03

A program ismét egy számjegyet nyomtat a tizedesvessző után. Ha ios::fixed vagy ios::scientific van beállítva, a pontossági érték határozza meg a tizedesvessző utáni számjegyek számát. Ha egyik jelölő sem van beállítva, a pontossági érték határozza meg a jelentős számjegyek teljes számát. A resetiosflags manipulátor törli ezeket a jelzőket.

Radix

A dec, octés hex manipulátorok az alapértelmezett radixot állítják be a bemenethez és a kimenethez. Ha például beszúrja a hex manipulátort a kimeneti adatfolyamba, az objektum helyesen lefordítja az egész számok belső adatmegjelenítőit hexadecimális kimeneti formátumba. A számok kisbetűvel jelennek meg a számjegyekkel, ha a uppercase jelölő világos (az alapértelmezett); ellenkező esetben nagybetűvel jelennek meg. Az alapértelmezett radix dec (decimális).

Idézett sztringek (C++14)

Amikor sztringet szúr be egy streambe, egyszerűen lekérheti ugyanazt a sztringet a stringstream::str() tagfüggvény meghívásával. Ha azonban az extrakciós operátorral szeretné beszúrni a streamet egy új sztringbe egy későbbi időpontban, előfordulhat, hogy váratlan eredményt kap, mert a >> operátor alapértelmezés szerint leáll, amikor megtalálja az első szóköz karaktert.

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

Ez a viselkedés manuálisan leküzdhető, de a sztring kerekítésének kényelmesebbé tétele érdekében a C++14 hozzáadja a std::quoted stream manipulátort <iomanip>. Beszúráskor quoted() a sztringet egy elválasztójellel (alapértelmezés szerint dupla idézőjel " ' ) veszi körül, és a kinyeréskor a streamet úgy módosítja, hogy az összes karaktert kinyerje, amíg meg nem találja a végső elválasztó karaktert. A beágyazott idézőjeleket a rendszer alapértelmezés szerint menekülési karakterrel ('\\' ) meneküli meg.

A határolók csak a streamobjektumban vannak jelen; nem szerepelnek a kinyert sztringben, de a basic_stringstream::stráltal visszaadott sztringben vannak.

A beszúrási és kinyerési műveletek térbeli viselkedése független attól, hogy egy sztring hogyan jelenik meg a kódban, ezért az idézett operátor attól függetlenül hasznos, hogy a bemeneti sztring nyers sztringkonstans vagy normál sztring. A bemeneti sztring formátumától függetlenül tartalmazhat beágyazott idézőjeleket, sortöréseket, tabulátorokat és így tovább, és ezeket a quoted() manipulátor megőrzi.

További információkért és teljes kód példákért lásd: quoted.

Lásd még:

kimeneti streamek