Apa perbedaan antara istringstream, ostringstream dan stringstream? / Mengapa tidak menggunakan stringstream di setiap kasus?

163

Kapan saya akan menggunakan std::istringstream, std::ostringstreamdan std::stringstreammengapa saya tidak menggunakannya std::stringstreamdi setiap skenario (apakah ada masalah kinerja runtime?).

Terakhir, apakah ada hal buruk tentang ini (daripada menggunakan streaming sama sekali):

std::string stHehe("Hello ");

stHehe += "stackoverflow.com";
stHehe += "!";
Oliver Baur
sumber

Jawaban:

119

Secara pribadi, saya merasa sangat jarang bahwa saya ingin melakukan streaming masuk dan keluar dari aliran string yang sama.

Biasanya saya ingin menginisialisasi aliran dari string dan kemudian menguraikannya; atau mengalirkan sesuatu ke aliran string dan kemudian mengekstrak hasilnya dan menyimpannya.

Jika Anda streaming ke dan dari aliran yang sama, Anda harus sangat berhati-hati dengan keadaan aliran dan posisi aliran.

Menggunakan 'adil' istringstreamatau ostringstreammengekspresikan niat Anda dengan lebih baik dan memberi Anda beberapa pengecekan terhadap kesalahan konyol seperti penggunaan <<vs secara tidak sengaja >>.

Ada mungkin ada beberapa perbaikan kinerja tapi saya tidak akan melihat yang pertama.

Tidak ada yang salah dengan apa yang Anda tulis. Jika Anda menemukan itu tidak berkinerja cukup baik, maka Anda dapat membuat profil pendekatan lain, jika tidak tetap dengan yang paling jelas. Secara pribadi, saya hanya akan pergi untuk:

std::string stHehe( "Hello stackoverflow.com!" );
CB Bailey
sumber
22

A stringstreamagak lebih besar, dan mungkin memiliki kinerja yang sedikit lebih rendah - multiple inheritance dapat memerlukan penyesuaian ke pointer vtable. Perbedaan utamanya adalah (setidaknya secara teori) lebih baik dalam mengekspresikan niat Anda, dan mencegah Anda untuk tidak sengaja menggunakan >>tempat yang Anda maksudkan <<(atau sebaliknya). OTOH, perbedaannya cukup kecil sehingga terutama untuk bit cepat kode demonstrasi dan semacamnya, saya malas dan hanya menggunakan stringstream. Saya tidak dapat mengingat kapan terakhir kali saya secara tidak sengaja digunakan <<ketika saya bermaksud >>, jadi bagi saya bahwa sedikit keselamatan tampaknya sebagian besar teoretis (terutama karena jika Anda melakukan kesalahan seperti itu, hampir selalu akan sangat jelas segera).

Tidak ada yang salah dengan hanya menggunakan string, selama itu memenuhi apa yang Anda inginkan. Jika Anda hanya menyatukan string, mudah dan berfungsi dengan baik. Jika Anda ingin memformat jenis data lain, stringstreamakan mendukung, dan sebagian besar string tidak akan.

Jerry Coffin
sumber
17

Dalam kebanyakan kasus, Anda tidak akan membutuhkan input dan output pada stringstream yang sama, jadi menggunakan std::ostringstreamdan std::istringstreamsecara eksplisit membuat niat Anda jelas. Ini juga mencegah Anda mengetik secara tidak sengaja operator yang salah ( <<vs >>).

Ketika Anda perlu melakukan kedua operasi pada aliran yang sama Anda jelas akan menggunakan versi tujuan umum.

Masalah kinerja akan menjadi yang paling tidak menjadi perhatian Anda di sini, kejelasan adalah keuntungan utama.

Akhirnya tidak ada yang salah dengan menggunakan menambahkan string karena Anda harus membangun string murni. Anda tidak bisa menggunakannya untuk menggabungkan angka seperti yang Anda bisa dalam bahasa seperti perl.

Markus B
sumber
8

istringstream adalah untuk input, ostringstream untuk output. stringstream adalah input dan output. Anda dapat menggunakan stringstream cukup banyak di mana-mana. Namun, jika Anda memberikan objek Anda ke pengguna lain, dan itu menggunakan operator >> sedangkan Anda di mana menunggu objek menulis saja, Anda tidak akan bahagia ;-)

PS: tidak ada yang buruk tentang itu, hanya masalah kinerja.

Scharron
sumber
2

Untuk menjawab pertanyaan ketiga Anda: Tidak, itu masuk akal. Keuntungan menggunakan stream adalah bahwa Anda dapat memasukkan segala jenis nilai yang operator<<didefinisikan, sementara Anda hanya bisa menambahkan string (baik C ++ atau C) ke a std::string.

David Thornley
sumber
1

Agaknya ketika hanya penyisipan atau hanya ekstraksi yang sesuai untuk operasi Anda, Anda bisa menggunakan salah satu versi awalan 'i' atau 'o' untuk mengecualikan operasi yang tidak diinginkan.

Jika itu tidak penting maka Anda dapat menggunakan versi i / o.

Rangkaian string yang Anda tampilkan benar-benar valid. Meskipun penggabungan menggunakan stringstream dimungkinkan, itu bukan fitur yang paling berguna dari stringstreams, yaitu untuk dapat memasukkan dan mengekstrak POD dan tipe data abstrak.

Amardeep AC9MF
sumber
1

std :: ostringstream :: str () membuat salinan konten stream, yang menggandakan penggunaan memori dalam beberapa situasi. Anda dapat menggunakan fungsi std :: stringstream dan rdbuf () untuk menghindari ini.

Lebih detail di sini: cara menulis ostringstream langsung ke cout

Gerhard Wesp
sumber
0

Mengapa membuka file untuk akses baca / tulis jika Anda hanya perlu membaca darinya, misalnya?

Bagaimana jika beberapa proses perlu dibaca dari file yang sama?

Assaf Lavie
sumber