Korzystanie z operatorów wstawiania i formatu kontrolującego
W tym temacie pokazano, jak kontrolować format i jak tworzyć operatory wstawiania dla własnych klas. Operator wstawiania (<<
), który jest wstępnie zaprogramowany dla wszystkich standardowych typów danych języka C++, wysyła bajty do obiektu strumienia wyjściowego. Operatory wstawiania współpracują ze wstępnie zdefiniowanymi "manipulatorami", które są elementami, które zmieniają domyślny format argumentów liczb całkowitych.
Format można kontrolować przy użyciu następujących opcji:
Szerokość danych wyjściowych
Aby wyrównać dane wyjściowe, należy określić szerokość danych wyjściowych dla każdego elementu, umieszczając setw
manipulator w strumieniu lub wywołując width
funkcję składową. W tym przykładzie wartości w kolumnie są wyrównane do prawej co najmniej 10 znaków:
// 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
Wiodące puste pusty są dodawane do dowolnej wartości mniejszej niż 10 znaków szerokości.
Aby wypełnić pole, użyj fill
funkcji składowej, która ustawia wartość znaku wypełnienia dla pól, które mają określoną szerokość. Wartość domyślna jest pusta. Aby wypełnić kolumnę liczb gwiazdkami, zmodyfikuj poprzednią for
pętlę w następujący sposób:
for (int i = 0; i <4; i++)
{
cout.width(10);
cout.fill('*');
cout << values[i] << endl;
}
Manipulator endl
zastępuje znak nowego wiersza ('\n'
). Dane wyjściowe wyglądają następująco:
******1.23
*****35.36
*****653.7
***4358.24
Aby określić szerokość elementów danych w tym samym wierszu, użyj setw
manipulatora:
// 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;
}
Funkcja składowa jest zadeklarowana w elemencie width
<iostream>
. Jeśli używasz setw
lub innego manipulatora z argumentami, musisz uwzględnić wartość <iomanip>
. W danych wyjściowych ciągi są drukowane w polu szerokości 6 i liczb całkowitych w polu szerokości 10:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
setw
i width
nie obcinaj wartości. Jeśli sformatowane dane wyjściowe przekraczają szerokość, cała wartość jest drukowana, z zastrzeżeniem ustawienia dokładności strumienia. Zarówno, jak setw
i width
dotyczy tylko następującego pola. Szerokość pola przywraca domyślne zachowanie (wymaganą szerokość) po wydrukowaniu jednego pola. Jednak pozostałe opcje formatowania strumienia pozostają w mocy do czasu zmiany.
Wyrównanie
Strumienie wyjściowe są domyślnie wyrównane do prawej. Aby wyrównać nazwy z lewej strony w poprzednim przykładzie i wyrównać je do prawej, zastąp pętlę for
w następujący sposób:
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6) << names[i]
<< resetiosflags(ios::left)
<< setw(10) << values[i] << endl;
Dane wyjściowe wyglądają następująco:
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
Flaga wyrównania po lewej stronie jest ustawiana przy użyciu setiosflags
manipulatora z modułem left
wyliczania. Ten moduł wyliczający jest zdefiniowany w ios
klasie, więc jego odwołanie musi zawierać ios::
prefiks. resetiosflags
Manipulator wyłącza flagę wyrównania po lewej stronie. W przeciwieństwie do width
i , efekt setiosflags
i setw
resetiosflags
jest trwały.
Dokładność
Wartość domyślna precyzji zmiennoprzecinkowej wynosi sześć. Na przykład liczba 3466.9768 jest drukowana jako 3466.98. Aby zmienić sposób drukowania tej wartości, użyj setprecision
manipulatora. Manipulator ma dwie flagi: fixed
i scientific
. W fixed
przypadku ustawienia liczba jest drukowana jako 3466.976800. Jeśli scientific
jest ustawiona, drukuje jako 3.4669773+003.
Aby wyświetlić liczby zmiennoprzecinkowe wyświetlane w obszarze Wyrównanie z jedną cyfrą znaczącą, zastąp pętlę for
w następujący sposób:
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 wyświetla tę listę:
Zoot 1
Jimmy 4e+01
Al 7e+02
Stan 4e+03
Aby wyeliminować notację naukową, wstaw tę instrukcję przed pętlą for
:
cout << setiosflags(ios::fixed);
W przypadku notacji stałej program drukuje jedną cyfrę po przecinku dziesiętny.
Zoot 1.2
Jimmy 35.4
Al 653.7
Stan 4358.2
Jeśli zmienisz flagę na ios::fixed
ios::scientific
, program wyświetli następujące polecenie:
Zoot 1.2e+00
Jimmy 3.5e+01
Al 6.5e+02
Stan 4.4e+03
Ponownie program drukuje jedną cyfrę po przecinku dziesiętny. Jeśli jest ustawiona wartość ios::fixed
lub ios::scientific
, wartość precyzji określa liczbę cyfr po przecinku dziesiętnego. Jeśli żadna z flag nie jest ustawiona, wartość precyzji określa całkowitą liczbę cyfr znaczących. resetiosflags
Manipulator czyści te flagi.
Podstawa
Manipulatory dec
, oct
i hex
ustawiają domyślny radix dla danych wejściowych i wyjściowych. Jeśli na przykład wstawisz hex
manipulator do strumienia wyjściowego, obiekt poprawnie tłumaczy wewnętrzną reprezentację danych całkowitych na format wyjściowy szesnastkowy. Liczby są wyświetlane z cyframi od f w małych literach, jeśli flaga uppercase
jest jasna (wartość domyślna); w przeciwnym razie są one wyświetlane w wielkim przypadku. Domyślny promień to dec
(dziesiętny).
Ciągi cytowane (C++14)
Po wstawieniu ciągu do strumienia można łatwo pobrać ten sam ciąg, wywołując funkcję składową stringstream::str()
. Jeśli jednak chcesz użyć operatora wyodrębniania, aby wstawić strumień do nowego ciągu w późniejszym momencie, może zostać wyświetlony nieoczekiwany wynik, ponieważ >>
operator domyślnie zatrzyma się po znalezieniu pierwszego znaku odstępu.
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
To zachowanie można przezwyciężyć ręcznie, ale aby ciąg był bardziej wygodny, C++14 dodaje std::quoted
manipulator strumienia w programie <iomanip>
. Po wstawieniu quoted()
otacza ciąg ogranicznikiem (domyślnie podwójny cudzysłów " " " ) i po wyodrębnieniu przetwarza strumień w celu wyodrębnienia wszystkich znaków do momentu znalezienia końcowego ogranicznika. Wszystkie osadzone cudzysłowy są domyślnie poprzedzone znakiem ucieczki ("\\").
Ograniczniki są obecne tylko w obiekcie strumienia; nie są obecne w wyodrębnionym ciągu, ale znajdują się w ciągu zwróconym przez basic_stringstream::str
element .
Zachowanie białych znaków operacji wstawiania i wyodrębniania jest niezależne od tego, jak ciąg jest reprezentowany w kodzie, dlatego operator cytowany jest przydatny niezależnie od tego, czy ciąg wejściowy jest nieprzetworzonym literałem ciągu, czy zwykłym ciągiem. Ciąg wejściowy, niezależnie od formatu, może zawierać osadzone cudzysłowy, podziały wierszy, tabulatory itd., a wszystkie te wartości zostaną zachowane przez quoted()
manipulator.
Aby uzyskać więcej informacji i pełnych przykładów kodu, zobacz quoted
.