Bab. 7 Masukan/Keluaran Aliran
Tujuan
Instruksional
|
|
·
Header pustaka iostream.
·
Keluaran aliran.
·
Masukan aliran.
·
I/O tak-terformat read, write, dan gcount.
|
·
Pengenalan
manipulator aliran.
·
Keadaan format
aliran.
·
Keadaan error
aliran.
|
7.1 Introduksi
Pustaka standard C++ menyediakan
kapabilitas masukan/keluaran yang kaya. Bab ini akan mendiskusikan berbagai
kapabilitas yang umumnya dipakai di dalam operasi I/O. Hampir semua fitur I/O
yang akan didiskusikan berorientasi-objek. Hal ini akan memanfaatkan beberapa
fitur C++ yang lain, seperti referensi, overloading fungsi dan overloading
operator. Setiap operasi I/O dieksekusi dengan suatu cara yang sensitif
terhadap tipe data. Jika suatu fungsi telah didefinisikan untuk menangani tipe
data tertentu, maka fungsi anggota itu akan dipanggil untuk menangani tipe data
tersebut.
Pengguna dapat menspesifikasi bagaimana
melakukan operasi I/O untuk objek dengan tipe yang didefinisikan sendiri oleh
pengguna. Hal ini dilakukan dengan mengoverload operator penyisipan aliran
(<<) dan operator ekstraksi aliran (>>). Kemampuan ini merupakan
salah satu fitur paling penting di dalam C++.
7.2 Aliran
I/O
C++ terjadi di dalam aliran, yang merupakan runtun byte. Di dalam operasi
masukan, byte-byte tersebut mengalir dari suatu divais (misalnya papanketik,
disk drive, koneksi jaringan, dan lainnya) ke memori utam. Di dalam operasi
keluaran, byte-byte mengalir dari memori utama ke suatu divais (misalnya layar,
printer, disk drive, koneksi jaringan, dan lainnya).
Byte
dapat merepresentasikan karakter, data mentah, citra, suara digital, video
digital, atau informasi lain yang dibutuhkan oleh suatu aplikasi. Mekenisme I/O
sistem harus memindahkan runtun byte dari divais ke memori utama (dan
sebaliknya) secara konsisten dan handal. Pemindahan semacam itu seringkali
melibatkan putaran mekanikal, seperti rotasi cakram atau tape. Waktu yang
dibutuhkan pemindahan seperti ini secara umum jauh lebih besar daripada waktu
yang diperlukan oleh processor untuk memanipulasi data secara internal.
C++
menyediakan kedua kapabilitas “level-rendah” dan “level-tinggi”. Kapabilitas
I/O level-rendah (yaitu, I/O tak-terformat) menspesifikasi jumlah byte yang
akan dipindahkan divais-ke-memori atau memori-ke-divais. Pada pemindahan
semacam itu, byte secara individu merupakan fokus pekerjaan. Kapabilitas
level-rendah mendukung pemindahan data berkecepatan tinggi.
Programer
umumnya menyukai kapabilitas level-tinggi (I/O terformat), dimana byte-byte
dikelompokkan menjadi unit-unit seperti integer, angka-pecahan, karakter,
string, dan tipe yang didefinisikan pengguna. Kapabilitas berorientasi-tipe ini
jauh lebih disukai di dalam operasi I/O dibandingkan dengan kapabilitas
level-rendah.
7.2.1 Objek dan Kelas Aliran
Masukan/Keluaran
Pustaka
iostream menyediakan banyak template
untuk menangani operasi-operasi I/O. Sebagai contoh, template kelas basic_istream mendukung operasi
masukan-aliran, template kelas basic_ostream
mendukung operasi aliran-keluaran, dan template kelas basic_iostream mendukung kedua aliran-masukan dan aliran-keluaran.
Setiap template mempunya spesialisasi template terdefinisi yang memampukan
operasi I/O char. Selain itu, pustaka
iostream menyediakan sehimpunan typedef untuk memberikan nama-nama alias
bagi spesialisasi template. Penspesifikasi typedef
mendeklarasikan sinonim (nama alias) untuk tipe data tertentu. Anda akan sering
melihat penggunaan typedef untuk
menciptakan nama tipe data yang lebih mudah dibaca dan yang lebih pendek.
Sebagai contoh, statemen
typedef Kartu *KartuPtr;
mendefinisikan
nama alias, KartuPtr, sebagai sinonim
untuk tipe Kartu *. Penciptaan nama
alias menggunakan typedef tidak
berarti menciptakan tipe data; typedef
hanya menciptakan nama tipe. typedef
istream merepresentasikan sebuah spesialisasi dari basic_istream yang memampukan masukan char. Dengan alur yang sama, typedef
ostream merepresentasikan sebuah spesialisasi dari basic_ostream yang memampukan keluaran char. Begitu juga typedef
iostream merepresentasikan sebuah spesialisasi basic_iostream yang memampukan kedua masukan dan keluaran char. Anda akan sering melihat
penggunaan typedef pada bab ini.
Hirarki Template
Aliran I/O dan Overloading Operator
Template
basic_istream dan basic_ostream keduanya diderivasi
melalui pewarisan tunggal dari template basis basic_ios1. Template basic_iostream
diderivasi melalui pewarisan jamak dari template basic_istream dan basic_ostream.
Diagram kelas UML pada Gambar 7.1 menyimpulkan relasi pewarisan ini.
Gambar
7.1 Hirarki pewarisan template aliran I/O
Overloading operator menyediakan notasi
sederhana dalam melaksanakan operasi masukan/keluaran. Operator geser-kiri
(<<) dioverload untuk melakukan
operasi keluaran aliran dan dikenal dengan operator penyisipan aliran. Operator
geser-kanan (>>) dioverload
untuk melakukan operasi masukan aliran dan dikenal dengan operator ekstraksi
aliran. Kedua operator tersebut digunakan bersama dengan objek aliran standard cin, cout,
cerr, dan clog.
Objek Aliran
Standard cin, cout, cerr, dan clog
Objek
terdefinisi cin merupakan sebuah
instans istream dan dikatakan
“terkoneksi ke” divais masukan standard, yang biasanya adalah papanketik.
Operator ekstraksi aliran (>>) yang dipakai di dalam statemen berikut
menyebabkan suatu nilai untuk variabel integer skor (diasumsikan bahwa skor
telah dideklarasikan sebagai sebuah variabel int) menjadi masukan dari cin
ke memori:
cin >> skor; // data "mengalir" sesuai
arah panah
Kompiler
menentukan tipe data dari skor dan
menyeleksi operator ekstraksi aliran teroverload
yang sesuai dengan tipe data itu. Operator >> dioverload untuk memasukkan data bertipe fundamental, string, dan
pointer.
Objek
terdefinisi cout merupakan sebuah
instans ostream dan dikatakan
“terkoneksi ke” divais keluaran standard, yang biasanya adalah layar monitor.
Operator penyisipan aliran (<<) yang dipakai di dalam statemen berikut
menyebabkan suatu nilai untuk variabel integer skor (diasumsikan bahwa skor
telah dideklarasikan sebagai sebuah variabel int) menjadi keluaran dari memori ke divais keluaran standard:
cout <<
skor; // data "mengalir" sesuai arah panah
Kompiler
menentukan tipe data dari skor dan
menyeleksi operator penyisipan aliran teroverload
yang sesuai dengan tipe data itu. Operator << dioverload untuk memasukkan data bertipe fundamental, string, dan
pointer.
Objek
terdefinisi cerr merupakan sebuah
instans ostream dan dikatakan
“terkoneksi ke” divais keluaran standard, yang biasanya adalah layar monitor.
Keluaran ke objek cerr tidak
disangga, yang mengimplikasikan bahwa setiap penyisipan aliran ke cerr akan menyebabkan keluarannya
ditampilkan segera. Hal ini untuk memberitahu pengguna tentang kejadian error
pada program.
Objek
terdefinisi clog merupakan sebuah
instans ostream dan dikatakan
“terkoneksi ke” divais keluaran standard, yang biasanya adalah layar monitor.
Keluaran ke objek clog disangga, yang
mengimplikasikan bahwa setiap penyisipan aliran ke clog akan ditampung di dalam suatu penyangga (area memori).
Penyanggaan merupakan suatu teknik peningakatan kinerja I/O yang dipelajari di
dalam matakuliah Sistem Operasi.
Gambar
7.2 Hirarki pewarisan template aliran I/O untuk pemrosesan
file
Template
Pemrosesan File
Pemrosesan
file di dalam C++ menggunakan template kelas basic_ifstream (untuk masukan file), basic_ofstream (untuk keluaran file), dan basic_fstream (untuk masukan dan keluaran file). Setiap template
kelas memiliki spesialisasi template terdefinisi yang memampukan I/O char. C++ menyediakan sehimpunan typedef untuk nama alias bagi
spesialisasi template yang ada. Misalnya, typedef
ifstream merepresentasikan sebuah spesialisasi dari basic_ifstream untuk memampukan masukan char dari suatu file. Dengan alur yang sama, typedef ofstream merepresentasikan sebuah spesialisasi dari basic_ofstream untuk memampukan keluaran
char ke suatu file. Dan juga, typedef fstream merepresentasikan sebuah
spesialisasi dari basic_fstream untuk
memampukan masukan char dari dan
keluaran char ke suatu file. Template
basic_ifsteam mewarisi dari basic_istream, basic_ofstream mewarisi dari basic_ostream,
dan basic_fstream mewarisi dari basic_iostream. Diagram kelas UML pada
Gambar 7.2 menyimpulkan sebagian dari hirarki pewarisan I/O.
7.3 Keluaran Aliran
Kapabilitas
keluaran terformat dan tak-terformat disediakan oleh ostream. Kapabilitas ini mencakup keluaran dari tipe data standard
dengan operator penyisipan aliran (<<); keluaran dari karakter melalui
fungsi anggota put; keluaran
tak-terformat melalui fungsi anggota write;
keluaran dari integer dari format desimal, oktal, dan heksadesimal; keluaran
dari nilai pecahan dengan berbagai kepresisian; keluaran dari data dengan lebar
bidang tertentu; dan lainnya.
7.3.1 Keluaran dari Variabel char *
C++
menentukan tipe data secara otomatis, kelebihan dari C. Misalnya, diinginkan
untuk menampilkan alamat yang disimpan di dalam suatu pointer char *. Operator << telah
dioverload sehingga bisa menampilkan char
* sebagai string yang diterminasi oleh null. Untuk menampilkan alamat, Anda
bisa meng-cast char * menjadi void *
(hal ini bisa dilakukan kepada sembarang variabel pointer). Gambar 7.3
mendemonstrasikan program yang bisa menampilkan variabel char * dalam format string dan format alamat. Alamat yang ditampilkan
di sini dalam basis 16 (heksadesimal).
Gambar 7.1 Menggunakan Spesialisasi Template Fungsi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// Gambar 7.3: gambar7_03.cpp
// Printing the address stored in a char *
variable.
#include <iostream>
using namespace std;
int main()
{
const char *const kata = "cinta";
// menampilkan nilai dari char *, kemudian
menampilkan nilai dari
// static_cast to void *
cout << "Nilai dari kata
adalah: " << kata << endl
<< "Nilai dari
static_cast< void * >( kata ) adalah: "
<< static_cast< void * >( kata ) <<
endl;
} // akhir dari main
|
Nilai
dari kata adalah: cinta
Nilai dari
static_cast< void * >( kata ) adalah: 00428300
7.3.2 Keluaran Karakter Menggunakan Fungsi Anggota
put
Anda
dapat menggunakan fungsi anggota put
untuk menampilkan karakter. Sebagai contoh, statemen
cout.put( 'A' );
menampilkan
karakter tunggal A. Pemanggilan terhadap put
dapat dibuat bertingkat, seperti di dalam statemen
cout.put( 'A' ).put( '\n' );
7.4 Masukan Aliran
Sekarang
akan didiskusikan tentang masukan aliran. Kapabilitas masukan terformat dan
tak-terformat disediakan oleh istream.
Operator ekstraksi aliran (>>) normalnya melompati karakter spasi putih
(seperti spasi, tab, dan garis-baru) di dalam aliran masukan; nanti akan
didiskusikan bagaimana mengubah watak ini. Setelah tiap masukan, operator
ekstraksi aliran memberikan nilai balik berupa sebuah referensi yang menunjuk
ke objek aliran yang menerima pesan ekstraksi (objek aliran adalah cin di dalam ekspresi cin>>skor). Jika referensi itu
digunakan sebagai kondisi (misalnya di dalam kondisi kontinuasi loop statemen while), maka fungsi operator cast teroverload void * secara
implisit dipanggil untuk mengkonversi referensi menjadi sebuah nilai pointer
tak-null atau pointer null tergantung dari sukeses tidaknya operasi masukan
terakhir. Sebuah pointer tak-null mengkonversi referensi tersebut menjadi nilai
bool, true, untuk mengindikasikan kesuksesan dan pointer null
mengkonversinya menjadi nilai bool, false, untuk mengindikasikan kegagalan.
Ketika pembaacaan dilakukan melewati ujung akhir suatu aliran, maka operator
cast teroverload void * menghasilkan pointer null untuk mengindikasikan end-of-file.
Setiap
objek aliran memuat beberapa bit keadaan yang digunakan untuk mengendalikan
keadaan aliran (misalnya untuk pemformatan, penetapan keadaan error, dan
lainnya). Bit-bit tersebut digunakan oleh operator cast teroverload void * untuk
menentukan apakah menghasilkan nilai balik sebuah pointer tak-null atau pointer
null. Ekstraksi aliran menyebabkan failbit
ditetapkan 1 jika dibaca tipe data yang salah dan menyebabkan badbit ditetapkan 1 jika operasi masukan
mengalami kegagalan.
7.4.1 Fungsi Anggota get dan getline
Fungsi
anggota get tanpa argumen membaca
satu karakter dari aliran (termasuk karakter spasi putih dan karakter
non-grafik, seperti runtun kunci yang merepresentasikan end-of-file) dan menjadikan karakter tersebut sebagai nilai balik
dari pemanggilan fungsi. Fungsi get menghasilkan nilai balik EOF ketika
end-of-file ditemukan di dalam aliran.
Fungsi Anggota
eof, get, dan put
Gambar
7.4 mendemonstrasikan fungsi anggota eof
dan get pada aliran masukan cin dan fungsi anggota put pada aliran keluaran cout. Program terlebih dahulu
menampilkan nilai dari cin.eof(),
dimana false (0 pada keluaran) untuk menunjukkan bahwa end-of-file tidak
terjadi pada cin. Pengguna kemudian
memasukkan sebaris teks dan menekan ENTER yang diikuti dengan end-of-file
(<Ctrl>-z pada Windows, <Ctrl>-d pada UNIX dan Macintosh). Baris 15
membaca setiap karakter, dimana baris 16 mengirim keluaran ke cout menggunakan fungsi anggota put.
Ketika end-of-file dijumpai, statemen while berhenti, dan baris 20 menampilkan nilai cin.eof(), yang sekarang bernilai true (1 pada keluaran), untuk menunjukkan bahwa end-of-file telah
dijumpai pada cin. Program ini
menggunakan fungsi anggota get
tanpa-argumen dan menghasilkan nilai balik berupa karakter yang sedang dibaca
(baris 15). Fungsi eof menghasilkan
nilai balik true hanya jika program
mencoba membaca melewati karakter terakhir di dalam aliran.
Fungsi
anggota get dengan satu argumen
referensi-karakter membaca karakter selanjutnya dari aliran masukan (meski jika
yang dibaca adalah karakter spasi putih) dan menyimpannya di dalam argumen
karakter. Versi fungsi get ini
menghasilkan nilai balik berupa referensi yang menunjuk ke objek istream.
Versi
ketiga fungsi get mengambil tiga
argumen, yaitu sebuah array karakter, batas ukuran, dan sebuah pembatas (atau
delimiter dengan nilai default ‘\n’). Versi ini membaca karakter dari aliran
masukan. Ia membaca satu karakter lebih sedikit dari jumlah karakter maksimum
yang dispesifikasi dan berhenti jika delimiter dibaca. Karakter null disisipkan
untuk menghentikan string masukan di dalam array karakter yang digunakan
sebagai penyangga oleh program. Delimiter tidak ditempatkan di dalam array
karakter tetapi tetap berada di dalam aliran masukan (delimiter menjadi
karakter pertama selanjutnya yang dibaca). Jadi, hasil dari pemanggilan kedua
dari get adalah baris kosong, kecuali
jika karakter delimiter dihapus dari aliran masukan (bisa juga dengan cin.ignore()).
Gambar 7.4 Menggunakan Fungsi Anggota get, put, dan
eof
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// Gambar 7.4: gambar7_04.cpp
// Menggunakan fungsi anggota get, put dan
eof.
#include <iostream>
using namespace std;
int main()
{
int karakter; // menggunakan int, karena char tidak bisa
merepresentasikan EOF
// meminta pengguna memasukkan sebaris teks
cout << "Sebelum
masukan, cin.eof() adalah " << cin.eof() << endl
<< "Masukkan
sebaris teks diikuti dengan end-of-file:" << endl;
// menggunakan get untuk membaca setiap karakter;
menggunakan put untuk menampilkannya
while(
( karakter = cin.get() )
!= EOF )
cout.put( karakter );
//
menampilkan karakter end-of-file
cout << "\nEOF di
dalam sistem ini adalah: " << karakter << endl;
cout << "Setelah
masukan EOF, cin.eof() adalah " << cin.eof() <<
endl;
} // akhir dari main
|
Sebelum
masukan, cin.eof() adalah 0
Masukkan
sebaris teks diikuti dengan end-of-file:
Menguji
fungsi anggota get dan put
^Z
EOF
di dalam sistem ini adalah: -1
Setelah masukan
EOF, cin.eof() adalah 1
Membandingkan
cin dan cin.get
Gambar
7.5 membandingkan masukan menggunakan ekstraksi aliran dengan cin (yang membaca karakter sampai
karakter spasi-putih ditemukan) dan menggunakan cin.get. Pemanggilan terhadap cin.get
(baris 22) tidak menspesifikasi sebuah delimiter, sehingga karakter default
‘\n’ digunakan.
Gambar 7.5 Membandingkan cin dan cin.get
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// Gambar 7.5: gambar7_05.cpp
// Membandingkan cin dan cin.get.
#include <iostream>
using namespace std;
int main()
{
//
menciptakan dua array char, masing-masing dengan 80 elemen
const
int UKURAN = 80;
char buffer1[ UKURAN ];
char buffer2[ UKURAN ];
//
menggunakan cin membaca karakter ke buffer1
cout
<< "Masukkan sebuah kalimat:" << endl;
cin >> buffer1;
//
menampilkan isi buffer1
cout << "\nString yang dibaca
dengan cin adalah:" << endl
<< buffer1 << endl <<
endl;
//
menggunakan cin.get untuk membaca karakter ke buffer2
cin.get( buffer2, UKURAN );
// menampilkan isi buffer2
cout << "String yang dibaca
dengan cin.get adalah:" << endl
<< buffer2 << endl;
} // akhir dari main
|
Masukkan
sebuah kalimat:
Membandingkan
masukan string dengan cin dan cin.get
String
yang dibaca dengan cin adalah:
Membandingkan
String
yang dibaca dengan cin.get adalah:
masukan string dengan cin dan cin.get
Menggunakan
Fungsi Anggota getline
Fungsi
anggota getline bekerja mirip dengan
versi ketiga dari fungsi anggota get
dan menyisipkan sebuah karakter null setelah baris teks di dalam array
karakter. Fungsi getline membuang
delimiter dari aliran, tetapi tidak menyimpannya di dalam array karakter.
Program pada Gambar 7.6 mendemonstraskan penggunaan fungsi anggota getline pada sebaris teks (baris 13).
Gambar 7.6 Menggunakan Fungsi Anggota getline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// Gambar 7.6: gambar7_06.cpp
// Membaca karakter menggunakan fungsi
anggota geline.
#include <iostream>
using namespace std;
int main()
{
const int UKURAN = 80;
char buffer[ UKURAN ]; // menciptakan
array yang memuat 80 karakter
// memasukkan karakter ke dalam buffer via
getline
cout << "Masukkan sebuah
kalimat:" << endl;
cin.getline( buffer, UKURAN );
// menampilkan isi buffer
cout << "\nKalimat
yang dimasukkan adalah:" << endl << buffer <<
endl;
} // akhir dari main
|
Masukkan sebuah kalimat:
Penggunaan fungsi anggota
getline
Kalimat yang dibaca adalah:
Penggunaan fungsi anggota
getline
7.4.2 Fungsi Anggota istream: peek, putback, dan
ignore
Fungsi
anggota ignore dari kelas istream membaca dan membuang sejumlah
karakter (default satu karakter) atau berhenti bila menjumpai delimiter
tertentu (default adalah EOF, yang menyebabkan ignore untuk melompat ke
end-of-file ketika membaca dari suatu file). Fungsi anggota putback menempatkan kembali karakter
sebelumnya yang didapatkan oleh get
dari sebuah aliran masukan ke aliran tersebut. Fungsi anggota peek menjadikan nilai balik karakter
selanjutnya dari sebuah aliran masukan tidak tidak membuang karakter tersebut
dari aliran.
7.5 I/O Tak-Terformat Menggunakan read, write, dan
gcount
Masukan/keluaran
tak-terformat dilakukan menggunakan fungsi anggota read dan write dari kelas
istream dan ostream. Fungsi anggota read
membaca byte demi byte dari suatu array karakter. Byte-byte ini tidak
terformat. Sebagai contoh,
char
buffer[] = "SELAMAT
ULANG TAHUN";
cout.write(
buffer, 10
);
menampilkan
10 byte pertama dari buffer (termasuk
karakter null, jika ada, yang akan menyebabkan keluaran dengan cout dan << untuk berhenti).
Pemanggilan
cout.write( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10 );
menampilkan
10 karakter pertama. Fungsi anggota read
membaca sejumlah karakter yang ditentukan ke dalam suatu array karakter.
Jika yang dibaca lebih sedikit dari
jumlah karakter yang ditentukan, maka failbit
ditetapkan 1. Fungsi gcount
melaporkan jumlah karakter yang dibaca oleh operasi masukan terakhir.
Gambar
7.7 mendemonstrasikan fungsi anggota read
dan gcount dari kelas istream, dan fungsi anggota write dari kelas ostream. Program membaca 20 karakter (dari runtun masukan yang
lebih panjang) ke dalam array buffer
dengan fungsi read (baris 13),
menentukan jumlah karakter yang dibaca dengan gcount (baris 17) dan menampilkan karakter-karakter yang ada di
dalam buffer dengan fungsi write (baris 17).
Gambar 7.7 I/O Tak-Terformat Menggunakan read,
gcount, dan write
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// Gambar 7.7: gambar7_07.cpp
// I/O tak-terformat menggunakan read,
gcount dan write.
#include <iostream>
using namespace std;
int main()
{
const int UKURAN = 80;
char buffer[ UKURAN ]; // menciptakan array 80 karakter
// menggunakan fungsi read untuk memasukkan
karakter ke buffer
cout << "Masukkan sebuah
kalimat:" << endl;
cin.read( buffer, 20 );
// menggunakan fungsi write dan gcount untuk
menampilkan isi buffer
cout << endl << "Kalimat
yang dimasukan adalah:" << endl;
cout.write( buffer, cin.gcount() );
cout << endl;
} // akhir dari main
|
Masukkan
sebuah kalimat:
Menggunakan
fungsi anggota read, write, dan gcount
Kalimat
yang dimasukkan adalah:
Menggunakan fungsi
a
7.6 Pengenalan Manipulator Aliran
C++
menyediakan berbagai manipulator aliran yang melakukan tugas pemformatan.
Manipulator aliran menyediakan beberapa kapabilitas seperti menetapkan lebar
bidang, menetapkan kepresisian, menetapkan dan tidak-menetapkan keadaan format,
menetapkan karakter pengisi di dalam bidang, mengalirkan aliran, menyisipkan
karakter garis-baru ke dalam aliran keluaran, menyisipkan karakter null ke
dalam aliran keluaran, dan melompati spasi putih di dalam aliran masukan.
Fitur-fitur ini akan dijelaskan sebentar lagi.
7.6.1 Basis Aliran Integral: dec, oct, hex, dan
setbase
Integer
diinterpretasikan sebagai nilai desimal (basis-10). Untuk mengubah basis dimana
di dalamnya integer diinterpretasikan pada suatu aliran, sisipkan menipulator hex untuk menetapkan basis heksadesimal
(basis-16) atau sisipkan manipulator oct
untuk menetapkan basis oktal (baris-8). Anda bisa menyisipkan manipulator dec untuk menetapkan-ulang basis aliran
menjadi desimal.
Basis
aliran dapat diubah menggunakan manipulator aliran setbase, yang memerlukan sebuah argumen int (10, 8, atau 16) untuk menetapkan basis menjadi desimal, oktal,
atau heksadesimal. Karena setbase
memerlukan satu argumen, fungsi ini dikenal dengan manipulasi aliran
terparameterisasi. Penggunaan setbase
(atau sembarang manipulator terparameterisasi) memerlukan pencantuman header
<iomanip>. Nilai basis aliran
tetap sama sampai diubah secara eksplisit. Gambar 7.8 mendemonstrasikan
manipulator aliran hex, oct, dec,
dan setbase.
Gambar 7.8 Menggunakan manipulator aliran hex, oct,
dec, dan setbase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// Gambar 7.8: gambar7_08.cpp
// Menggunakan manipulator aliran hex, oct,
dec dan setbase.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int angka;
cout << "Masukkan suatu angka
desimal: ";
cin >> angka; // memasukkan angka
// menggunakan manipulator hex untuk
menampilkan angka heksadesimal
cout << angka << " dalam
desimal adalah: " << hex
<< angka << endl;
// menggunakan manipulator oct untuk
menampilkan angka oktal
cout << dec << angka << " dalam
oktal adalah: "
<< oct << angka << endl;
// menggunakan manipulator setbase untuk
menampilkan angka desimal
cout << setbase( 10 ) << angka << " dalam
desimal adalah: "
<< angka << endl;
} // akhir dari main
|
Masukkan
suatu angka desimal: 20
20
dalam heksadesimal adalah: 14
20
dalam oktal adalah: 24
20 dalam desimal
adalah: 20
7.6.2 Kepresisian Pecahan: precision dan
setprecision
Anda
dapat mengendalikan kepresisian angka pecahan (jumlah digit di sebelah kanan
titik desimal) menggunakan manipulator aliran setprecision atau fungsi anggota precision dari kelas ios_base.
Pemanggilan terhadap fungsi anggota precision
tanpa-argumen menghasilkan nilai balik berupa pengaturan kepresisian saat ini.
Program pada Gambar 7.9 menggunakan fungsi precision
(baris 22) dan manipulator setprecision
(baris 31) untuk menampilkan sebuah tabel yang menampilkan akar kuadrat dari 2,
dengan kepresisian bervariasi dari 0 sampai 9.
Gambar 7.9 Mengendalikan Kepresisian Nilai Pecahan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// Gambar 7.9: gambar7_09.cpp
// Mengendalikan kepresisian atas nilai
pecahan.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
double akar2 = sqrt( 2.0 ); //
menghitung akar kuadrat dari 2
int presisi; // kepresisian,
bervariasi dari 0-9
cout << "Akar kuadrat 2 dengan
kepresisian 0-9." << endl
<< "Kepresisian ditetapkan
menggunakan fungsi anggota "
<< "ios_base:"
<< endl;
cout << fixed; // menggunakan notasi titik-tetap
// menampilkan akar kuadrat menggunakan
fungsi ios_base
for ( presisi = 0; presisi <= 9;
++presisi )
{
cout.precision( presisi );
cout << akar2 << endl;
} // akhir dari for
cout << "\nKepresisian
ditetapkan menggunakan manipulator aliran "
<< "setprecision:"
<< endl;
// menetapkan
kepresisian untuk setiap dijit, kemudian menampilkan akar kuadrat
for ( presisi = 0; presisi <= 9;
++presisi )
cout << setprecision( presisi ) << akar2
<< endl;
} // akhir dari main
|
Akar
kuadrat 2 dengan kepresisian 0-9.
Kepresisian ditetapkan menggunakan fungsi
anggota ios_base:
1
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142136
1.41421356
1.414213562
Kepresisian
ditetapkan menggunakan manipulator aliran setprecision:
1
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142136
1.41421356
1.414213562
7.6.3 Lebar Bidang: width dan setw
Fungsi
anggota width (dari kelas basis ios_base) menetapkan lebar bidang
(jumlah posisi karakter dimana di dalamnya sebuah nilai ditampilkan atau jumlah
karakter maksimum yang dibaca) dan memberikan nilai balik berupa lebar bidang
sebelumnya. Jika nilai yang ditampilkan lebih sempit dari lebar bidang, maka
karakter pengisi disisipkan sebagai pengganjal. Nilai yang lebih lebar dari
lebar yang ditentukan akan dipotong. Fungsi width
tanpa argumen menjadikan pengaturan saat ini sebagai nilai balik.
Gambar
7.10 mendemonstrasikan penggunaan fungsi anggota width pada masukan dan keluaran. Pada masukan yang dibaca ke dalam
sebuah array char, jumlah maksimum
karakter yang bisa dibaca adalah lebar bidang dikurangi satu. Hal ini karena
karakter null akan ditempatkan di dalam string masukan. Ingat bahwa ekstraksi
aliran berhenti ketika spasi putih dijumpai. Manipulator aliran setw juga dapat digunakan untuk
menetapkan lebar bidang.
Gambar 7.10 Mendemonstrasikan Fungsi width
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// Gambar 7.10: gambar7_10.cpp
// Mendemonstrasikan fungsi width.
#include <iostream>
using namespace std;
int main()
{
int nilaiLebar = 4;
char kalimat[ 10 ];
cout << "Masukkan sebuah
kalimat:" << endl;
cin.width( 5 ); // memasukkan
hanya 5 karakter dari kalimat
// menetapkan lebar bidang, kemudian menampilkan
karakter berdasarkan lebar tersebut
while
( cin >> kalimat )
{
cout.width( nilaiLebar++ );
cout
<< kalimat << endl;
cin.width( 5 ); // memasukkan
5 karakter lagi dari kalimat
} //
akhir dari while
} // akhir dari main
|
Masukkan sebuah kalimat:
Ini adalah sebuah pengujian fungsi anggota
width
Ini
adal
ah
sebu
ah
peng
ujia
n
fung
si
angg
ota
widt
h
7.6.4 Manipulator Aliran Keluaran yang
Didefinisikan Pengguna
Anda
dapat menciptakan manipulator aliran sendiri. Gambar 7.11 menampilkan
penciptaan dan penggunaan manipulator aliran terparameterisasi baru bell (baris 8-11), carriageReturn (baris 14-17), tab
(baris 20-23), dan endLine (baris
27-30). Untuk manipulator aliran keluaran, tipe nilai balik dan tipe parameter
harus stream &. Ketika baris 35
menyisipkan manipulator endLine di
dalam aliran keluaran, fungsi endLine
dipanggil dan baris 29 menampilkan runtun escape
\n dan manipulator flush kepada
aliran keluaran standard cout. Begitu
juga, ketika baris 35-44 menyisipkan manipulator tab, bell, dan carriageReturn di dalam aliran keluaran,
fungsi tab (baris 20), bell (baris 8), dan carriageReturn (baris 14) dipanggil, yang pada gilirannya
menampilkan berbagai runtun escape.
Gambar 7.11 Menciptakan dan Menguji Manipulator
Aliran Sendiri
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
// Gambar 7.11: gambar7_11.cpp
// Menciptakan dan menguji manipulator
aliran
// tak-terparameterisasi dan didefinisikan
sendiri oleh pengguna
#include <iostream>
using namespace std;
// manipulator bell (menggunakan runtun
escape \a)
ostream& bell( ostream& keluaran )
{
return
keluaran << '\a'; // mengeluarkan bunyi bip bip
} // akhir manipulator bell
// manipulator carriageReturn (menggunakan
runtun \r)
ostream& carriageReturn( ostream&
keluaran )
{
return
keluaran << '\r'; // mengeluarkan carriage return
} // akhir dari manipulator carriageReturn
// manipulator tab (menggunakan runtun
escape \t)
ostream& tab( ostream& keluaran )
{
return
keluaran << '\t'; // mengeluarkan tab
} // akhir dari manipulator tab
// manipulator endLine (menggunakan runtun
escape \n dan
// fungsi anggota flush)
ostream& endLine( ostream& keluaran
)
{
return
keluaran << '\n' << flush; // mengeluarkan seperti end of line
} // akhir dari manipulator endLine
int main()
{
// menggunakan manipulator tab dan endLine
cout << "Menguji manipulator
tab:" << endLine
<< 'a' << tab << 'b'
<< tab
<< 'c' << endLine;
cout << "Menguji manipulator
carriageReturn dan bell:"
<< endLine << "..........";
cout << bell; // menggunakan manipulator bell
// menggunakan manipulator carriageReturn
dan endLine
cout << carriageReturn << "-----"
<< endLine;
} // akhir dari main
|
Mengiji
manipulator tab:
a
b c
Menguji
manipulator carriageReturn dan bell:
-----.....
7.7 Keadaan Format Aliran dan Manipulator Aliran
Berbagai
manipulator aliran dapat digunakan untuk menspesifikasi jenis pemformatan yang
akan dilakukan selama operasi aliran I/O. Manipulator aliran mengendalikan
pengaturan format keluaran. Gambar 7.12 menjelaskan setiap manipulator aliran
yang mengendalikan keadaan format aliran. Akan disajikan pula beberapa contoh
pengendali format aliran pada beberapa bagian ke depan.
Gambar
7.12 Keadaan Format Aliran dari <iostream>
Manipulator
|
Penjelasan
|
skipsw
left
right
internal
boolalpha
dec
oct
hex
showbase
showpoint
uppercase
showpos
scientific
fixed
|
Melompati karakter spasi
putih pada suatu aliran masukan. Pengaturan ini diatur-ulang dengan
manipulator aliran noskipws.
Menyejajarkan keluaran ke
kiri di dalam suatu bidang. Mengganjal karakter di sebelah kanan bila
diperlukan.
Menyejajarkan keluaran ke
kanan di dalam suatu bidang. Mengganjal karakter di sebelah kiri bila
diperlukan.
Mengindikasikan bahwa
tanda angka (positif atau negatif) harus disejajarkan ke kiri di dalam suatu
bidang dan magnitudo angka harus disejajarkan ke kanan di dalam bidang yang
sama (dengan cara mengganjal karakter antara tanda dan angka).
Menspesifikasi bahwa
nilai bool harus ditampilkan
sebagai kata true atau false. Manipulator nboolalpha menetapkan-ulang aliran
untuk menampilkan nilai bool
sebagai 1 (true) dan 0 (false).
Menspesifikasi bahwa
integer harus diperlakukan sebagai nilai desimal (basis 10).
Menspesifikasi bahwa
integer harus diperlakukan sebagai nilai oktal (basis 8).
Menspesifikasi bahwa
integer harus diperlakukan sebagai nilai heksadesimal (basis 16).
Menspesifikasi bahwa
basis suatu angka ditampilkan di depan angka tersebut ( 0 untuk oktal; 0x
atau 0X untuk heksadesimal). Pengaturan ini diatur-ulang dengan manipulator
aliran noshowbase.
Menspesifikasi bahaw
angka pecahan harus ditampilkan dengan sebuah titik desimal. Ini biasanya
dilakukan dengan fixed untuk
menjamin bahwa sejumlah dijit tertentu
tetap ditampilkan di sebelah kanan titik desimal, meskipun terdari-dari dijit
nol. Pengaturan ini diatur-ulang dengan manipulator noshowpoint.
Menspesifikasi bahwa
huruf besar ( X dan A sampai F) harus digunakan di dalam sebuah integer
heksadesimal dan bahwa huruf besar E harus digunakan ketika merepresentasikan
sebuah nilai pecahan dalam notasi saintifik. Pengaturan ini diatur-ulang
dengan manipulator aliran nonuppercase.
Menspesifikasi bahwa
angka positif harus diawali dengan tanda +. Pengaturan ini diatur-ulang
dengan manipulator aliran noshowpos.
Menspesifikasi keluaran
dari nilai pecahan dalam notasi saintifik.
Menspesifikasi keluaran
dari nilai pecahan dalam notasi titik-tetap dengan jumlah dijit tertentu di
sebelah kanan titik desimal.
|
7.7.1 Ekor Nol dan Titik Desimal (showpoint)
Manipulator
aliran showpoint memaksa suatu angka
pecahan untuk ditampilkan dengan titik desimal dan ekor nol. Sebagai contoh,
nilai pecahan 79.0 akan ditampilkan 79 apabila tanpa menggunakan showpoint dan ditampilkan 79.000000
(atau sebanyak mungkin ekor nol yang diinginkan) bila menggunakan showpoint. Untuk mereset atau
mengatur-ulang pengaturan showpoint,
gunakan manipulator aliran noshowpoint.
Program
pada Gambar 7.13 menunjukkan bagaimana menggunakan ekor nol dan titik desimal
untuk nilai pecahan. Ingat bahwa kepresisian default atas angka pecahan adalah
6. Ketika tidak ada manipulator aliran fixed
atau scientific yang digunakan, maka
kepresisian merepresentasikan jumlah dijit signifikan yang akan ditampilkan.
Gambar 7.13 Mengendalikan Penampilan Ekor Nol dan
Titik Desimal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// Gambar 7.13: gambar7_13.cpp
// Mengendalikan penampilan ekor nol dan
// titik desimal di dalam nilai pecahan.
#include <iostream>
using namespace std;
int main()
{
// menampilkan nilai double dengan format
aliran default
cout << "Sebelum menggunakan
showpoint" << endl
<<
"9.9900 ditampilkan sebagai: " << 9.9900 << endl
<< "9.9000 ditampilkan
sebagai: " << 9.9000 << endl
<< "9.0000 ditampilkan
sebagai: " << 9.0000 << endl << endl;
// menampilkan nilai double setelah
showpoint
cout << showpoint
<< "Setelah menggunakan
showpoint" << endl
<< "9.9900 ditampilkan
sebagai: " << 9.9900 << endl
<< "9.9000 ditampilkan
sebagai: " << 9.9000 << endl
<< "9.0000 ditampilkan
sebagai: " << 9.0000 << endl;
} // akhir dari main
|
Sebelum
menggunakan showpoint
9.9900
ditampilkan sebagai: 9.99
9.9000
ditampilkan sebagai: 9.9
9.0000
ditampilkan sebagai: 9
Sesudah
menggunakan showpoint
9.9900
ditampilkan sebagai: 9.99000
9.9000
ditampilkan sebagai: 9.90000
9.0000 ditampilkan
sebagai: 9.00000
7.7.2 Penyejajaran (left, right, dan internal)
Manipulator
left dan right memampukan Anda untuk menyejajarkan bidang ke kiri dengan
mengganjal karakter di sebelah kanan atau untuk menyejajarkan bidang ke kanan
dengan mengganjal karakter di sebelah kiri. Karakter pengganjal dispesifikasi
oleh fungsi anggota fill atau
manipulator aliran terparameterisasi setfill.
Gambar 7.14 menggunakan manipulator setw,
left, dan right untuk menyejajarkan ke kiri dan ke kanan suatu bidang data
integer.
Gambar 7.14 Penyejajaran Kiri dan Kanan dengan left
dan right
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// Gambar 7.14: gambar7_14.cpp
// Penyejajaran kiri dan kanan dengan
manipulator aliran left dan right.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int x = 12345;
// menampilkan x disejajarkan ke kanan
(default)
cout << "Default adalah
penyejajaran kanan:" << endl
<< setw( 10 ) << x;
// menggunakan
manipulator left untuk menampilkan x disejajarkan ke kiri
cout << "\n\nMenggunakan
std::left untuk menyejajarkan x ke kiri:\n"
<< left << setw( 10 ) << x;
// menggunakan manipulator right untuk menampilkan x
disejajarkan ke kanan
cout << "\n\nMenggunakan
std::right untuk menyejajarkan x ke kanan:\n"
<< right << setw( 10 ) << x << endl;
} // akhir dari main
|
Default adalah penyejajaran kanan:
12345
Menggunakan std::left untuk menyejajarkan x ke kiri:
12345
Menggunakan std::right untuk menyejajarkan x ke
kanan:
12345
Manipulator
aliran internal mengindikasikan bahwa
tanda suatu angka (atau basis ketika menggunakan manipulator aliran showbase) harus disejajarkan ke kiri di
dalam sebuah bidang, bahwa magnitudo harus disejajarkan ke kanan, dan bahwa
spasi di antara keduanya (antara tanda dan magnitudo) harus diganjal dengan
karakter pengisi. Gambar 7.15 menampilkan manipulator aliran internal untuk menspesifikasi penspasian
internal (baris 10). Perhatikan bahwa showpos
memaksa tanda positif pada saat ditampilkan (baris 10). Untuk mengatur-ulang
showpos, Anda bisa menggunakan manipulator aliran noshowpos.
Gambar 7.15 Menampilkan
Integer dengan Penspasian Internal dan Tanda Positif
1
2
3
4
5
6
7
8
9
10
11
|
// Gambar 7.15: gambar7_15.cpp
// Menampilkan suatu integer dengan
penspasian internal dan tanda positif.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//
menampilkan nilai dengan penspasian internal dan tanda positif
cout << internal << showpos << setw( 10 ) << 123
<< endl;
} // akhir dari main
|
+ 123
7.7.3 Pengganjalan (fill dan setfill)
Fungsi
anggota fill menspesifikasi karakter
pengisi untuk digunakan di dalam bidang penyejajaran; spasi secara default
digunakan untuk pengganjalan. Fungsi ini menghasilkan nilai balik berupa
karakter pengganjal yang dipakai sebelumnya. Manipulator setfill juga menetapkan karakter pengganjal. Gambar 7.16
mendemonstrasikan fungsi fill (baris
30) dan manipulator aliran setfill
(baris 34 dan 37) untuk menetapkan karakter pengisi.
Gambar 7.16 Menggunakan fill dan setfill
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// Gambar 7.16: gambar7_16.cpp
// Menggunakan fungsi anggota fill dan
manipulator aliran setfill
// untuk mengubah karakter pengisi.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int x = 10000;
// menampilkan x
cout << x << " ditampilkan
sebagai int yang disejajarkan ke kiri dan ke kanan\n"
<< "dan
sebagai heksadesimal dengan penyejajaran internal.\n"
<< "Menggunakan
karakter pengganjal default (spasi):" << endl;
// menampilkan x dengan basis
cout << showbase << setw( 10 )
<< x << endl;
// menampilkan x dengan penyejajaran kiri
cout << left << setw( 10 )
<< x << endl;
// menampilkan x sebagai heksadesimal dengan
penyejajaran internal
cout << internal << setw( 10 ) << hex
<< x << endl << endl;
cout << "Menggunakan berbagai
karakter pengganjal:" << endl;
// menampilkan x dengan penyejajaran ke
kanan
cout << right;
cout.fill( '*' );
cout << setw( 10 ) << dec
<< x << endl;
//
menampilkan x dengan penyejajaran ke kiri
cout << left << setw( 10 )
<< setfill( '%' )
<< x << endl;
// menampilkan x dengan penyejajaran
internal
cout << internal << setw( 10 )
<< setfill( '^' )
<< hex
<< x << endl;
} // akhir dari main
|
10000
ditampilkan sebagai int yang disejajarkan ke kiri dan ke kanan
dan
sebagai heksadesimal dengan penyejajaran internal.
Menggunakan
karakter pengganjal default (spasi):
10000
10000
0x 2710
Menggunakan berbagai karakter pengganjal:
******10000
10000%%%%%%
0x^^^^^2710
7.7.4 Basis Aliran (dec, oct, hex, dan showbase)
C++
menyediakan manipulator aliran dec, hex, dan oct untuk menspesifikasi integer agar ditampilkan sebagai desimal,
heksadesimal, dan oktal. Penyisipan aliran default adalah desimal jika tidak
ada manipulator yang digunakan. Dengan ekstraksi aliran, integer yang diawali
dengan 0 diperlakukan sebagai nilai oktal, integer yang diawali dengan 0x atau
0X diperlakukan sebagai heksadesimal, dan semua integer lainnya diperlakukan
sebagai nilai desimal. Bagitu basis tertentu dispesifikasi untuk suatu aliran,
semua integer pada aliran tersebut akan diproses menggunakan basis itu sampai
basis berbeda dispesifikasi atau sampai program berhenti mengeksekusi.
Manipulator
aliran showbase memaksa basis suatu
integer untuk ditampilkan. Angka desimal ditampilkan secara default, angka
oktal ditampilkan dengan 0 di bagian depan, dan angka heksadesimal ditampilkan
dengan 0x atau 0X di bagian depan. Gambar 7.17 mendemonstrasikan kegunaan
manipulator aliran showbase untuk memaksa suatu integer agar ditampilkan dalam
format desimal, oktal, dan heksadesimal. Untuk mengatur-ulang pengaturan showbase, digunakan manipulator aliran noshowbase.
Gambar 7.17 Menggunakan showbase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// Gambar 7.17: gambar7_17.cpp
// Menggunakan manipulator aliran showbase.
#include <iostream>
using namespace std;
int main()
{
int x = 100;
// menggunakan showbase untuk menampilkan
basis bilangan
cout << "Menampilkan
integer yang diawali dengan basisnya masing-masing:" <<
endl
<< showbase;
cout << x << endl; // menampilkan
nilai desimal
cout << oct << x << endl;
// menampilkan nilai oktal
cout << hex << x << endl;
// menampilkan nilai heksadesimal
} // akhir dari main
|
Menampilkan integer yang diawali dengan basisnya
masing-masing:
100
0144
0x64
7.7.5 Notasi Angka Pecahan: scientific dan fixed
Manipulator
aliran scientific dan fixed mengendalikan format keluaran
angka pecahan. Manipulator scientific memaksa keluaran angka pecahan untuk
ditampilkan dalam format saintifik. Manipulator aliran fixed memaksa angka pecahan untuk ditampilkan sebanyak sejumlah
dijit (seperti dispesifikasi oleh fungsi anggota precision atau manipulator
aliran setprecision) di sebelah kanan titik desimal. Gambar 7.18
mendemonstrasikan penampilan angka pecahan di dalam format tetap dan format
saintifik menggunakan manipulator aliran scientific
(18) dan fixed (22). Format eksponen
di dalam notasi saintifik bisa berbeda pada kompiler yang tidak sama.
Gambar 7.18 Menggunakan scientific dan fixed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// Gambar 7.18: gambar7_18.cpp
// Menampilkan nilai pecahan pada defualt
sistem,
// dalam format tetap dan format saintifik.
#include <iostream>
using namespace std;
int main()
{
double
x = 0.001234567;
double
y = 1.946e9;
//
menampilkan x dan y dalam format default
cout << "Ditampilkan dalam
format default:" << endl
<< x << '\t' << y
<< endl;
// menampilkan x dan y dalam format
saintifik
cout << "\nDitampilkan dalam
format saintifik:" << endl
<< scientific << x << '\t' << y
<< endl;
// menampilkan x dan y dalam format tetap
cout << "\nDitampilkan dalam
format tetap:" << endl
<< fixed << x << '\t' << y
<< endl;
} // akhir dari main
|
Ditampilkan dalam format default:
0.001234567 1.946e+009
Ditampilkaan dalam format saintifik:
1.234567e-003 1.946000e+009
Ditampilkaan dalam format tetap:
0.0012345 1946000000.000000
7.7.6 Kendali Huruf Besar/Huruf Kecil
Manipulator
aliran uppercase menampilkan huruf
besar X atau E dengan nilai heksadesimal atau dengan notasi saintifik atas
nilai pecahan (Gambar 7.19). Penggunaan manipulator aliran uppercase menyebabkan semua huruf di dalam suatu nilai heksadesimal
menjadi huruf besar. Secara default, huruf untuk nilai heksadesimal dan
eksponen di dalam notasi saintifik atas nilai pecahan selalu huruf kecil. Untuk
mengatur-ulang pengaturan uppercase,
Anda bisa menggunakan manipulator aliran nouppercase.
Gambar 7.19 Menggunakan scientific dan fixed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Gambar 7.19: gambar7_19.cpp
// Manipulator aliran uppercase.
#include <iostream>
using namespace std;
int main()
{
cout
<< "Menampilkan huruf besardi dalam notasi" <<
endl
<<
"saintifik dan nilai desimal:" << endl;
// menggunakan
std:uppercase untuk menampilkan huruf besar; menggunakan
// std::hex dan std::showbase untuk menampilkan nilai
heksa dan basisnya
cout << uppercase << 4.345e10 << endl
<< hex << showbase <<
123456789 << endl;
} // akhir dari main
|
Menampilkan huruf besardi dalam notasi
saintifik dan nilai desimal:
4.345E+010
0X75BCD15
7.7.7 Kendali Huruf Besar/Huruf Kecil
C++
menyediakan tipe data bool, yang
memiliki nilai true atau false, sebagai nilai alternatif bagi 0
dan 1 (tak-nol). Secara default, sebuah variabel bool menampilkan 0 atau 1. Namun, Anda bisa menggunakan manipulator
aliran boolalpha untuk menetapkan
aliran keluaran untuk menampilkan nilai bool sebagai string “true” atau “false”. Manipulator aliran noboolalpha
dipakai untuk menetapkan aliran keluaran dalam menampilkan nilai bool sebagai integer (kembali ke
pengaturan default). Program pada Gambar 7.20 mendemonstrasikan kedua
manipulator aliran ini. Baris 11 menampilkan nilai bool, yang pada baris 8 ditetapkan true, sebagai suatu integer. Baris 15 menggunakan manipulator boolalpha untuk menampilkan nilai bool sebagai sebuah string. Baris 18-19
kemudian mengubah nilai bool kembali
menjadi integer menggunakan manipulator noboolalpha.
Gambar 7.20 Mendemonstrasikan boolalpha dan
noboolalpha
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// Gambar 7.20: gambar7_20.cpp
// Mendemonstrasikan manipulator aliran
boolalpha dan noboolalpha.
#include <iostream>
using namespace std;
int main()
{
bool
nilaiBoolean = true;
// menampilkan default true booleanValue
cout << "nilaiBoolean adalah
" << nilaiBoolean << endl;
// menampilkan nilaiBoolean setelah
menggunakan boolalpha
cout << "nilaiBoolean (setelah
menggunakan boolalpha) adalah "
<< boolalpha << nilaiBoolean << endl
<< endl;
cout << "menukar nilaiBoolean
dan menggunakan noboolalpha" << endl;
nilaiBoolean = false; // mengubah
nilaiBoolean
cout << noboolalpha << endl; // menggunakan
noboolalpha
// menampilkan default false nilaiBoolean
setelah menggunakan noboolalpha
cout
<< "nilaiBoolean adalah " << nilaiBoolean
<< endl;
//
menampilkan booleanValue setelah menggunakan boolalpha kembali
cout
<< "nilaiBoolean (setelah menggunakan boolalpha) adalah
"
<< boolalpha << nilaiBoolean << endl;
} // akhir dari main
|
nilaiBoolean adalah 1
nilaiBoolean (setelah menggunakan boolalpha) adalah
true
menukar nilaiBoolean dan menggunakan noboolalpha
nilaiBoolean adalah 0
nilaiBoolean (setelah menggunakan boolalpha) adalah
false
7.7.8 Menetapkan Keadaan Format
Sekarang
akan didiskusikan bagaimana menghasilkan nilai balik berupa format aliran.
Fungsi anggota flags tanpa argumen
menghasilkan nilai balik berupa pengaturan format sekarang sebagai tipe data fmtflags (dari kelas ios_base), yang merepresentasikan
keadaan format. Fungsi anggota flags
dengan satu argumen fmtflags
menetapkan keadaan format seperti yang dispesifikasi oleh argumen dan
menghasilkan nilai balik berupa pengaturan keadaan sebelumnya. Nilai pengaturan
awal yang dijadikan nilai balik oleh flags
bisa berbeda pada sistem yang tak sama. Program pada Gambar 7.21 menggunakan
fungsi anggota flags untuk menyimpan
keadaan format asli dari aliran (baris 17), dan kemudian mengembalikannya
kembali ke pengaturan format asli pada baris 25.
Gambar 7.21 Mendemonstrasikan Fungsi Anggota flags
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// Gambar 7.21: gambar7_21.cpp
// Mendemonstrasikan fungsi anggota flags.
#include <iostream>
using namespace std;
int main()
{
int nilaiInteger = 1000;
double nilaiDouble = 0.0947628;
// menampilkan nilai flags, nilai int dan
double (format asli)
cout << "Nilai
variabel flags yang direstorasi adalah: " << cout.flags()
<< "\nMenampilkan nilai
dalam format asli:\n"
<< nilaiInteger << '\t'
<< nilaiDouble << endl << endl;
//
menggunakan fungsi cout flags untuk menyimpan format asli
ios_base::fmtflags formasAsli
= cout.flags();
cout << showbase
<< oct << scientific; // mengubah format
// menampilkan nilai flags, nilai int dan
double (format baru)
cout << "Nilai
variabel flags yang direstorasi adalah: " <<
<< "\nMenampilkan nilai
dalam format baru:\n"
<< nilaiInteger << '\t'
<< nilaiDouble << endl << endl;
cout.flags( formatAsli ); // merestorasi format
// menampilkan nilai flags, nilai int dan
double (format asli)
cout << "Nilai variabel flags
yang direstorasi adalah: "
<< cout.flags()
<< "\nMenampilkan nilai dalam
format asli kembali:\n"
<< nilaiInteger << '\t'
<< nilaiDouble << endl;
} // akhir dari main
|
nilaiBoolean adalah 1
nilaiBoolean (setelah menggunakan boolalpha) adalah
true
menukar nilaiBoolean dan menggunakan noboolalpha
nilaiBoolean adalah 0
nilaiBoolean (setelah menggunakan boolalpha) adalah
false
7.8 Keadaan Error Aliran
Keadaan
suatu aliran diuji di dalam kelas ios_base.
Akan didemonstrasikan bagaimana menguji keadaan error aliran pada Gamabr 7.22. eofbit dipakai untuk menetapkan aliran
masukan setelah ditemukan end-of-file.
Sebuah program dapat menggunakan fungsi anggota eof untuk menentukan apakah end-of-file telah ditemukan pada suatu
aliran atau tidak. Pemanggilan
cin.eof()
menghasilkan
nilai balik true jika end-of-file
ditemukan pada cin dan false jika sebaliknya.
failbit dipakai untuk sebuah aliran
ketika error format terjadi dan tidak ada karakter yang dimasukkan (yaitu,
ketika Anda membaca sebuah angka dan pengguna pengguna mengentri sebuah
string). Ketika error semacam itu terjadi, karakter tersebut tidak hilang.
Fungsi anggota fail melaporkan apakah
operasi aliran telah mengalami kegagal atau tidak.
Gambar 7.21 Mendemonstrasikan Fungsi Anggota flags
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
// Gambar 7.22: gambar7_22.cpp
// Menguji keadaan error.
#include <iostream>
using namespace std;
int main()
{
int nilaiInteger;
// menampilkan hasil dari fungsi-fungsi cin
cout << "Sebelum operasi
masukan buruk terjadi:"
<< "\ncin.rdstate(): "
<< cin.rdstate()
<< "\n cin.eof(): "
<< cin.eof()
<< "\n cin.fail():
" << cin.fail()
<< "\n cin.bad(): "
<< cin.bad()
<< "\n cin.good():
" << cin.good()
<< "\n\nMengharapkan
suatu integer, tetapi dimasukkan sebuah karakter: ";
cin >> nilaiInteger; // memasukkan
nilai karakter
cout << endl;
// menampilkan hasil setelah masukan buruk
cout << "Setelah operasi
masukan buruk terjadi:"
<< "\ncin.rdstate(): "
<< cin.rdstate()
<< "\n cin.eof(): "
<< cin.eof()
<< "\n cin.fail():
" << cin.fail()
<< "\n cin.bad(): "
<< cin.bad()
<< "\n cin.good():
" << cin.good()
<< endl << endl;
cin.clear(); // membersihkan aliran
// menampilkan hasil setelah membersihkan
aliran
cout << "Setelah cin.clear()"
<< "\ncin.fail():
" <<
<< "\ncin.good(): "
<< cin.good()
<< endl;
} // akhir dari main
|
Sebelum operasi masukan buruk terjadi:
cin.rdstate():
0
cin.eof():
0
cin.fail():
0
cin.bad():
0
cin.good():
1
Mengharapkan suatu integer, tetapi dimasukkan
sebuah karakter: A
Mengharapkan suatu integer, tetapi dimasukkan
sebuah karakter:
cin.rdstate():
2
cin.eof():
0
cin.fail():
1
cin.bad():
0
cin.good():
0
Setelah cin.clear()
cin.fail():
0
cin.good(): 1
badbit ditetapkan untuk sebuah aliran
ketika error yang terjadi menyebabkan data hilang. Fungsi anggota bad melaporkan apakah sebuah operasi
aliran gagal atau tidak. Secara umum, kegagalan serius semacam ini tidak dapat
diperbaiki.
goodbit ditetapkan untuk sebuah aliran
jika tidak ada eofbit, failbit, dan badbit yang bernilai true.
Fungsi anggota good menghasilkan true jika fungsi bad, fail, dan eof semuanya menghasilkan false. Operasi I/O seharusnya hanya
dilakukan pada aliran “baik” saja.
Fungsi
anggota rdstate menghasilkan nilai
balik berupa keadaan error aliran. Pemanggilan cout.rdstate, misalnya, akan menghasilkan keadaan aliran, yang
kemudian diuji oleh sebuah statemen switch yang memeriksa eofbit, badbit, dan goodbit.
Fungsi
anggota clear dipakai untuk
merestorasi keadaan aliran agar kembali “baik”, sehingga operasi I/O dapat
dilaksanakan pada aliran tersebut. Argumen default untuk clear adalah goodbit,
jadi statemen
cin.clear();
membersihkan
cin dan menetapkan goodbit untuk aliran tersebut. Statemen
cin.clear( ios::failbit )
menetapkan
failbit. Anda bisa melakukan ini ketika melakukan operasi
masukan pada cin dengan tipe yang
terdefinisi oleh pengguna dan mengalami masalah. Nama clear mungkin tidak cocok untuk konteks ini, tetapi hal ini benar
dalam konteks pemrograman.
Kesimpulan
I/O C++ terjadi di dalam aliran,
yang merupakan runtun byte. Di dalam operasi masukan, byte-byte tersebut
mengalir dari suatu divais (misalnya papanketik, disk drive, koneksi jaringan,
dan lainnya) ke memori utam. Di dalam operasi keluaran, byte-byte mengalir dari
memori utama ke suatu divais (misalnya layar, printer, disk drive, koneksi
jaringan, dan lainnya).
Kapabilitas keluaran terformat dan
tak-terformat disediakan oleh ostream.
Kapabilitas ini mencakup keluaran dari tipe data standard dengan operator penyisipan
aliran (<<); keluaran dari karakter melalui fungsi anggota put; keluaran tak-terformat melalui
fungsi anggota write; keluaran dari
integer dari format desimal, oktal, dan heksadesimal; keluaran dari nilai
pecahan dengan berbagai kepresisian; keluaran dari data dengan lebar bidang
tertentu; dan lainnya.
Operator ekstraksi aliran
(>>) normalnya melompati karakter spasi putih (seperti spasi, tab, dan
garis-baru) di dalam aliran masukan; nanti akan didiskusikan bagaimana mengubah
watak ini. Setelah tiap masukan, operator ekstraksi aliran memberikan nilai
balik berupa sebuah referensi yang menunjuk ke objek aliran yang menerima pesan
ekstraksi (objek aliran adalah cin di
dalam ekspresi cin>>skor). Jika
referensi itu digunakan sebagai kondisi (misalnya di dalam kondisi kontinuasi
loop statemen while), maka fungsi
operator cast teroverload void * secara
implisit dipanggil untuk mengkonversi referensi menjadi sebuah nilai pointer
tak-null atau pointer null tergantung dari sukeses tidaknya operasi masukan
terakhir. Sebuah pointer tak-null mengkonversi referensi tersebut menjadi nilai
bool, true, untuk mengindikasikan kesuksesan dan pointer null
mengkonversinya menjadi nilai bool, false, untuk mengindikasikan kegagalan.
Ketika pembaacaan dilakukan melewati ujung akhir suatu aliran, maka operator
cast teroverload void * menghasilkan pointer null untuk mengindikasikan end-of-file.
Masukan/keluaran tak-terformat
dilakukan menggunakan fungsi anggota read
dan write dari kelas istream dan ostream. Fungsi anggota read
membaca byte demi byte dari suatu array karakter. Byte-byte ini tidak
terformat.
Berbagai manipulator aliran dapat
digunakan untuk menspesifikasi jenis pemformatan yang akan dilakukan selama
operasi aliran I/O. Manipulator aliran mengendalikan pengaturan format
keluaran.
Latihan
1)
Tulislah sebuah program yang
menguji pemasukan nilai integer dalam format desimal, oktal, dan heksadesimal.
Tampilkan setiap integer yang dibaca program dalam ketiga format tersebut. Uji
program dengan data masukan beritu: 10, 010, 0x10.
2)
Tulislah sebuah program yang
menampilkan nilai pointer, menggunakan casting
kepada semua tipe data. Mana yang menghasilkan nilai yang aneh? Mana yang
menyebabkan error terjadi?
3)
Tulislah sebuah program yang
menguji hasil penampilan nilai integer 12345 dan nilai pecahan 1.2345 dalam
bidang berbagai ukuran. Apa yang terjadi ketika nilai-nilai tersebut
ditampilkan di dalam bidang yang memuat dijit lebih sedikit dibandingkan dengan
nilai-nilai tersebut?
4)
Tulislah sebuah program yang
memasukkan sebuah string dari papanketik dan menentukan panjang string
tersebut. Tampilkan string di dalam suatu bidang yang memiliki lebar dua kali
panjang string.
No comments:
Post a Comment