Menggunakan Operator Penyisipan dan Format Pengontrol

Topik ini menunjukkan cara mengontrol format dan cara membuat operator penyisipan untuk kelas Anda sendiri. Operator penyisipan (<<), yang telah diprogram sebelumnya untuk semua jenis data C++ standar, mengirim byte ke objek aliran output. Operator penyisipan bekerja dengan "manipulator" yang telah ditentukan sebelumnya, yang merupakan elemen yang mengubah format default argumen bilangan bulat.

Anda bisa mengontrol format dengan opsi berikut:

Lebar Output

Untuk menyelaraskan output, Anda menentukan lebar output untuk setiap item dengan menempatkan setw manipulator di aliran atau dengan memanggil width fungsi anggota. Contoh ini meratakan kanan nilai dalam kolom dengan lebar minimal 10 karakter:

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

Kosong di depan ditambahkan ke nilai apa pun yang lebarnya kurang dari 10 karakter.

Untuk mengayuh bidang, gunakan fill fungsi anggota, yang mengatur nilai karakter padding untuk bidang yang memiliki lebar yang ditentukan. Defaultnya adalah kosong. Untuk mengapit kolom angka dengan tanda bintang, ubah perulangan sebelumnya for sebagai berikut:

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

endl Manipulator menggantikan karakter baris baru ('\n'). Keluarannya terlihat seperti:

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

Untuk menentukan lebar elemen data dalam baris yang sama, gunakan setw manipulator:

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

Fungsi width anggota dinyatakan dalam <iostream>. Jika Anda menggunakan setw atau manipulator lain dengan argumen, Anda harus menyertakan <iomanip>. Dalam output, string dicetak di bidang lebar 6 dan bilangan bulat di bidang lebar 10:

   Zoot      1.23
  Jimmy     35.36
     Al     653.7
   Stan   4358.24

setw dan width jangan memotong nilai. Jika output yang diformat melebihi lebar, seluruh nilai mencetak, tunduk pada pengaturan presisi aliran. Baik setw dan width mempengaruhi bidang berikut saja. Lebar bidang kembali ke perilaku defaultnya (lebar yang diperlukan) setelah satu bidang dicetak. Namun, opsi format aliran lainnya tetap berlaku hingga diubah.

Penjajaran

Aliran output default ke teks rata kanan. Untuk meratakan kiri nama dalam contoh sebelumnya dan meratakan kanan angka, ganti perulangan for sebagai berikut:

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

Keluarannya terlihat seperti:

Zoot        1.23
Jimmy      35.36
Al         653.7
Stan     4358.24

Bendera rata kiri diatur dengan menggunakan setiosflags manipulator dengan left enumerator. Enumerator ini didefinisikan dalam ios kelas, sehingga referensinya harus menyertakan awalan ios:: . resetiosflags Manipulator mematikan bendera rata kiri. Tidak seperti width dan setw, efek dan setiosflagsresetiosflags bersifat permanen.

Presisi

Nilai default untuk presisi floating-point adalah enam. Misalnya, angka 3466.9768 mencetak sebagai 3466.98. Untuk mengubah cara nilai ini dicetak, gunakan setprecision manipulator. Manipulator memiliki dua bendera: fixed dan scientific. Jika fixed diatur, angka akan dicetak sebagai 3466.976800. Jika scientific diatur, ia mencetak sebagai 3.4669773+003.

Untuk menampilkan angka floating-point yang ditunjukkan dalam Perataan dengan satu digit signifikan, ganti perulangan for sebagai berikut:

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 mencetak daftar ini:

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

Untuk menghilangkan notasi ilmiah, sisipkan pernyataan ini sebelum perulangan for :

cout << setiosflags(ios::fixed);

Dengan notasi tetap, program mencetak dengan satu digit setelah titik desimal.

Zoot         1.2
Jimmy       35.4
Al         653.7
Stan      4358.2

Jika Anda mengubah bendera menjadi ios::fixedios::scientific, program mencetak ini:

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

Sekali lagi, program mencetak satu digit setelah titik desimal. Jika atau ios::fixedios::scientific diatur, nilai presisi menentukan jumlah digit setelah titik desimal. Jika tidak ada bendera yang diatur, nilai presisi menentukan jumlah total digit signifikan. Manipulator resetiosflags menghapus bendera-bendera ini.

Radix

decManipulator , oct, dan hex mengatur radix default untuk input dan output. Misalnya, jika Anda memasukkan hex manipulator ke aliran output, objek menerjemahkan representasi data internal bilangan bulat dengan benar ke dalam format output heksadesimal. Angka ditampilkan dengan digit a hingga f dalam huruf kecil jika uppercase bendera jelas (default); jika tidak, angka ditampilkan dalam huruf besar. Radiks default adalah dec (desimal).

String yang dikutip (C++14)

Saat Anda menyisipkan string ke dalam aliran, Anda dapat dengan mudah mengambil kembali string yang sama dengan memanggil stringstream::str() fungsi anggota. Namun, jika Anda ingin menggunakan operator ekstraksi untuk menyisipkan aliran ke string baru di titik selanjutnya, Anda mungkin mendapatkan hasil yang tidak terduga karena >> operator secara default akan berhenti ketika menemukan karakter spasi putih pertama.

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

Perilaku ini dapat diatasi secara manual, tetapi untuk membuat string round-tripping lebih nyaman, C++14 menambahkan std::quoted manipulator aliran di <iomanip>. Setelah penyisipan, quoted() mengelilingi string dengan pemisah (tanda kutip ganda ' ' ' secara default) dan setelah ekstraksi memanipulasi aliran untuk mengekstrak semua karakter sampai pemisah akhir ditemukan. Setiap tanda kutip yang disematkan diloloskan dengan karakter escape ('\\' secara default).

Pemisah hanya ada di objek stream; mereka tidak ada dalam string yang diekstrak tetapi ada dalam string yang dikembalikan oleh basic_stringstream::str.

Perilaku spasi kosong dari operasi penyisipan dan ekstraksi tidak bergantung pada bagaimana string diwakili dalam kode, sehingga operator yang dikutip berguna terlepas dari apakah string input adalah string mentah harfiah atau string reguler. String input, apa pun formatnya, dapat memiliki tanda kutip yang disematkan, pemisah baris, tab, dan sebagainya, dan semua ini akan dipertahankan oleh quoted() manipulator.

Untuk informasi selengkapnya dan contoh kode lengkap, lihat quoted.

Baca juga

output Aliran