Udostępnij za pośrednictwem


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 setwresetiosflags 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, octi 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::strelement .

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.

Zobacz też

Strumienie wyjściowe