Používání operátorů insertion a řízení formátu
Toto téma ukazuje, jak řídit formát a jak vytvořit operátory vložení pro vlastní třídy. Operátor vložení (<<
), který je předprogramovaný pro všechny standardní datové typy jazyka C++, odesílá bajty do objektu výstupního datového proudu. Operátory vložení pracují s předdefinovanými manipulátory, což jsou prvky, které mění výchozí formát celočíselného argumentu.
Formát můžete ovládat následujícími možnostmi:
Šířka výstupu
Pokud chcete zarovnat výstup, určete šířku výstupu pro každou položku umístěním setw
manipulátoru do datového proudu nebo voláním width
členské funkce. Tento příklad zarovná hodnoty ve sloupci alespoň 10 znaků doprava:
// 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
Úvodní prázdné hodnoty se přidají k libovolné hodnotě kratší než 10 znaků.
K nastavení pole použijte fill
členovou funkci, která nastaví hodnotu znaku odsazení pro pole, která mají zadanou šířku. Výchozí hodnota je prázdná. Pokud chcete vložit sloupec čísel s hvězdičkami, upravte předchozí for
smyčku následujícím způsobem:
for (int i = 0; i <4; i++)
{
cout.width(10);
cout.fill('*');
cout << values[i] << endl;
}
Manipulátor endl
nahradí znak nového řádku ('\n'
). Výstup vypadá takto:
******1.23
*****35.36
*****653.7
***4358.24
Pokud chcete zadat šířky datových prvků na stejném řádku, použijte setw
manipulátor:
// 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;
}
Členová width
funkce je deklarována v <iostream>
. Pokud používáte setw
nebo jiný manipulátor s argumenty, musíte zahrnout <iomanip>
. Ve výstupu se řetězce vytisknou v poli s šířkou 7 a celými čísly v poli s šířkou 10:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
setw
a width
neořízejte hodnoty. Pokud formátovaný výstup překročí šířku, vytiskne se celá hodnota podle nastavení přesnosti datového proudu. Oba setw
a width
ovlivňují pouze následující pole. Šířka pole se po vytištění jednoho pole vrátí k výchozímu chování (nezbytné šířce). Ostatní možnosti formátu streamu však zůstávají v platnosti, dokud se nezmění.
Zarovnání
Výstupní datové proudy jsou ve výchozím nastavení zarovnané doprava. Pokud chcete názvy v předchozím příkladu zarovnat doleva a čísla zarovnat doprava, nahraďte smyčku for
následujícím způsobem:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6) << names[i]
<< resetiosflags(ios::left)
<< setw(10) << values[i] << endl;
Výstup vypadá takto:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
Příznak zarovnání doleva je nastaven pomocí setiosflags
manipulátoru s enumerátorem left
. Tento enumerátor je definován ve ios
třídě, takže jeho odkaz musí obsahovat předponu ios::
. Manipulátor resetiosflags
vypne příznak zarovnání doleva. Na rozdíl od width
a setw
, účinek setiosflags
a resetiosflags
je trvalý.
Počet deset. míst
Výchozí hodnota pro přesnost s plovoucí desetinnou čárkou je šest. Například číslo 3466,9768 se vytiskne jako 3466,98. Pokud chcete změnit způsob tisku této hodnoty, použijte setprecision
manipulátor. Manipulátor má dva příznaky: fixed
a scientific
. Pokud fixed
je nastaveno, číslo se vytiskne jako 3466,976800. Pokud scientific
je nastaveno, vytiskne se jako 3,4669773+003.
Pokud chcete zobrazit čísla s plovoucí desetinou čárkou zobrazenou v zarovnání s jednou významnou číslicí, nahraďte smyčku for
následujícím způsobem:
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;
Program vytiskne tento seznam:
Zoot 1
Jimmy 4e+01
Al 7e+02
Stan 4e+03
Chcete-li odstranit vědecký zápis, vložte tento příkaz před smyčku for
:
cout << setiosflags(ios::fixed);
Při pevném zápisu program za desetinnou čárkou vytiskne jednu číslici.
Zoot 1.2
Jimmy 35.4
Al 653.7
Stan 4358.2
Pokud změníte příznak na ios::fixed
ios::scientific
, program vytiskne toto:
Zoot 1.2e+00
Jimmy 3.5e+01
Al 6.5e+02
Stan 4.4e+03
Program znovu vytiskne jednu číslici za desetinnou čárkou.
ios::fixed
Pokud je nastavena hodnota ios::scientific
přesnosti, určuje počet číslic za desetinnou čárkou. Pokud není nastaven žádný příznak, hodnota přesnosti určuje celkový počet významných číslic. Manipulátor resetiosflags
tyto příznaky vymaže.
Základ
Funkce dec
, oct
a hex
manipulátory nastavují výchozí radix pro vstup a výstup. Pokud například vložíte hex
manipulátor do výstupního datového proudu, objekt správně přeloží interní reprezentaci celých čísel do šestnáctkového výstupního formátu. Pokud je příznak jasný (výchozí), zobrazí se čísla s číslicemi a až f v malých písmenech uppercase
. V opačném případě se zobrazí velkými písmeny. Výchozí radix je dec
(desítková).
Řetězce s quoted (C++14)
Když vložíte řetězec do datového proudu, můžete snadno načíst stejný řetězec zpět voláním stringstream::str()
členské funkce. Pokud ale chcete použít operátor extrakce k vložení datového proudu do nového řetězce v pozdějším okamžiku, můžete získat neočekávaný výsledek, protože >>
operátor se ve výchozím nastavení zastaví, když najde první prázdný znak.
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
Toto chování lze překonat ručně, ale aby byl řetězcový kruhový přechod pohodlnější, C++14 přidá manipulátor datového std::quoted
proudu do <iomanip>
. Při vložení quoted()
řetězec ohraničte oddělovačem (ve výchozím nastavení dvojitou uvozovkou ' '' ) a při extrakci s datovým proudem se extrahuje všechny znaky, dokud se nenajde konečný oddělovač. Všechny vložené uvozovky se standardně uvozují řídicím znakem (\\).
Oddělovače jsou přítomné pouze v objektu datového proudu; nejsou přítomné v extrahovaném řetězci, ale nacházejí se v řetězci vráceném řetězcem basic_stringstream::str
.
Chování prázdných znaků operací vložení a extrakce je nezávislé na tom, jak je řetězec reprezentován v kódu, takže operátor uvozovek je užitečný bez ohledu na to, jestli je vstupní řetězec literálem nezpracovaného řetězce nebo běžným řetězcem. Vstupní řetězec, bez ohledu na jeho formát, může obsahovat vložené uvozovky, konce řádků, tabulátory a tak dále a všechny tyto hodnoty budou zachovány manipulátorem quoted()
.
Další informace a úplné příklady kódu naleznete v tématu quoted
.