Stream yang tinggal di dalam string
Kamu sudah mengenal cin dan cout, yaitu stream yang terhubung ke keyboard dan layar. String stream adalah ide yang sama, hanya saja datanya tinggal di std::string di memori. Kamu menulis ke dalamnya dengan << dan mengambil nilai dengan >>, persis seperti stream konsol, tapi tidak ada yang menyentuh terminal.
Satu ide itu menyelesaikan dua masalah sehari-hari: mem-parsing teks menjadi nilai-nilai bertipe, dan menyusun string terformat dari potongan-potongan campuran. Semuanya ada di header <sstream> dan tersedia dalam tiga jenis:
istringstream: hanya baca, untuk mem-parsing input.ostringstream: hanya tulis, untuk menyusun output.stringstream: dua arah.
ss.str() mengembalikan semua yang sudah ditulis sejauh ini sebagai string biasa. Operator << melakukan format int ke teks yang sama seperti cout, kamu hanya menangkap hasilnya alih-alih mencetaknya.
Parsing: ambil nilai bertipe
Kekuatan sebenarnya muncul dengan >>. Beri sebuah stream sebuah teks, dan ekstraksi akan mengonversi setiap token ke tipe yang kamu minta, sambil melewati spasi di antaranya. Inilah cara rapi untuk memecah satu baris menjadi beberapa field bertipe:
Setiap >> membaca sampai spasi berikutnya lalu mengonversi: "Ada" menjadi string, "36" menjadi int, "5.5" menjadi double. Perhatikan istringstream di sini: tipe yang khusus untuk input membuat jelas bahwa kamu hanya mem-parsing.
Mengonversi string ke angka (dengan aman)
Tugas yang sering muncul adalah mengubah satu string seperti "42" menjadi int. stringstream bisa melakukannya, dan memberi tahu apakah teks itu benar-benar angka yang sah, sesuatu yang tidak pernah dilakukan atoi:
Di sini ss >> value membaca 123, berhenti di a, dan dianggap berhasil. Jadi selalu validasi seluruh string kalau hal itu penting. Pengecekan yang andal adalah membaca angkanya, lalu memastikan tidak ada sisa yang berarti. Untuk konversi satu nilai yang sederhana, std::stoi, std::stod, dan teman-temannya lebih singkat; pakai stringstream saat satu string membawa beberapa nilai campuran.
Memecah string berdasarkan delimiter
Memecah teks adalah tugas string stream yang paling sering dicari di Google. Gabungkan stream dengan std::getline, yang bisa membaca sampai karakter delimiter apa pun, bukan hanya baris baru:
Pola while (getline(...)) terus berulang sampai stream habis, karena getline mengembalikan stream itu, dan stream bernilai false begitu tidak ada lagi yang tersisa. Setiap token dimasukkan ke vector, tempat alami untuk mengumpulkan potongan hasil split yang jumlahnya tidak tetap. Hapus argumen ketiga, maka kamu memecah berdasarkan token yang dipisah spasi dengan >>. Pilih delimiter yang sesuai dengan datamu.
Menyusun string di memori
Untuk arah sebaliknya, ostringstream merangkai string terformat tanpa risiko buffer overflow milik sprintf atau penggabungan manual yang rapuh. Ini sempurna untuk baris log, nama file, atau pesan yang dirangkai dari angka dan teks:
Semua format <iomanip> yang biasa kamu pakai dengan cout (setw, setfill, setprecision, hex) bekerja sama persis pada string stream, jadi output yang diberi padding, berlebar tetap, atau heksadesimal langsung tertangkap ke dalam string.
Jebakan: reset sebelum dipakai ulang
Jebakan yang mengenai semua orang adalah memakai ulang stream tanpa meresetnya. Begitu sebuah stream mencapai akhir datanya, flag eof dan fail-nya terkunci menyala, dan setiap >> berikutnya diam-diam tidak melakukan apa-apa. Tidak ada error, hanya nilai lama:
stringstream ss("10");
int a, b;
ss >> a; // a = 10, stream now at end -> eof flag set
ss.str("20"); // load new text...
ss >> b; // FAILS SILENTLY - error flags are still set, b is unchanged
Kamu harus menghapus status error dan isinya. Urutan yang benar adalah clear() dulu, lalu str():
Ada dua kesalahan terkait: ss.clear() mereset flag-nya tapi tidak mengosongkan buffer (pakai ss.str("") untuk itu), dan stringstream yang terus kamu tambahi dengan << akan terus membesar. Buat stream baru di dalam loop, jangan memakai ulang stream yang kotor di setiap iterasi.
Berikutnya: array
String stream memberimu cara rapi untuk mengubah teks menjadi nilai bertipe dan sebaliknya, sering kali sekaligus satu daftar, seperti vector yang kamu isi saat memecah CSV. Untuk menyimpan dan mengakses kumpulan nilai yang ukurannya tetap, kamu butuh container paling dasar di bahasa ini. Berikutnya kita akan membahas array: cara mendeklarasikannya, mengakses elemennya dengan indeks, menelusurinya dengan loop, dan menghindari akses di luar batas yang menyebabkan begitu banyak undefined behavior di C++.
Pertanyaan yang sering diajukan
Apa itu stringstream di C++?
std::stringstream adalah stream yang sumbernya string, bukan keyboard atau file. Kamu menulis ke dalamnya dengan << dan membacanya dengan >>, persis seperti cout dan cin, sehingga ia menjadi alat standar untuk mem-parsing teks dan menyusun string di memori. Ia ada di header <sstream>.
Bagaimana cara mengonversi string ke int di C++ dengan stringstream?
Masukkan teksnya ke stream lalu ekstrak ke sebuah angka: stringstream ss("42"); int n; ss >> n;. Cek if (ss) (atau if (ss >> n)) untuk memastikan konversinya benar-benar berhasil. Untuk kasus sederhana std::stoi lebih singkat, tapi stringstream unggul saat satu string berisi beberapa nilai campuran.
Kenapa aku perlu memanggil clear() pada stringstream?
Begitu sebuah stream mencapai akhir datanya, bit eof/fail-nya tetap menyala dan setiap >> berikutnya diam-diam tidak melakukan apa-apa. Kalau kamu memakai ulang stringstream yang sama dengan isi baru, panggil ss.clear() untuk mereset flag error itu, lalu ss.str(newText) untuk memuat data baru. Kalau tidak, pembacaan akan gagal diam-diam.