C # memiliki fitur sintaksis di mana Anda dapat menggabungkan banyak tipe data secara bersamaan dalam 1 baris.
string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;
Apa yang akan menjadi setara dalam C ++? Sejauh yang saya bisa lihat, Anda harus melakukan semuanya pada baris terpisah karena tidak mendukung banyak string / variabel dengan operator +. Ini baik-baik saja, tetapi tidak terlihat rapi.
string s;
s += "Hello world, " + "nice to see you, " + "or not.";
Kode di atas menghasilkan kesalahan.
c++
string
compiler-errors
concatenation
Nick Bolton
sumber
sumber
char *
pointer satu sama lain. Itulah yang menghasilkan kesalahan - karena menjumlahkan pointer adalah tidak masuk akal. Seperti disebutkan di bawah, buat setidaknya operan ke-1 menjadistd::string
, dan tidak ada kesalahan sama sekali.Jawaban:
Lihatlah artikel Guru Minggu Ini dari Herb Sutter: The String Formatters of Manor Farm
sumber
std::string s = static_cast<std::ostringstream&>(std::ostringstream().seekp(0) << "HelloWorld" << myInt << niceToSeeYouString).str();
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();
cukup banyak satu barisDalam 5 tahun tidak ada yang menyebutkan
.append
?sumber
s.append("One"); s.append(" line");
s.append("One").append(" expression");
Mungkin saya harus mengedit yang asli untuk menggunakan nilai balik dengan cara ini?s
pada baris yang berbeda dalam kode C # yang sama dan dalam kode C ++ yang tidak dikompilasi. C ++s += "Hello world, " + "nice to see you, " + "or not.";
yang diinginkannya adalah yang dapat dituliss.append("Hello world, ").append("nice to see you, ").append("or not.");
append
adalah bahwa ia juga berfungsi ketika string berisi karakter NUL.Literal array karakter tersebut bukan C ++ std :: string - Anda perlu mengonversinya:
Untuk mengonversi ints (atau jenis streamable lainnya), Anda dapat menggunakan boost lexical_cast atau menyediakan fungsi Anda sendiri:
Anda sekarang dapat mengatakan hal-hal seperti:
sumber
string("Hello world")
dilakukan melaluioperator+()
didefinisikan di kelasstring
. Jika tidak adastring
objek dalam ekspresi, rangkuman menjadi jumlah ar pointerchar*
.Kode Anda dapat ditulis sebagai 1 ,
... tapi saya ragu itu yang Anda cari. Dalam kasus Anda, Anda mungkin mencari aliran:
1 " dapat ditulis sebagai ": Ini hanya berfungsi untuk string literal. Penggabungan dilakukan oleh kompiler.
sumber
const char smthg[] = "smthg"
: / Apakah ini bug?#define
menggunakan senar Anda untuk menyiasatinya, meskipun ini membawa masalah sendiri.Menggunakan C ++ 14 literal yang ditentukan pengguna dan
std::to_string
kode menjadi lebih mudah.Perhatikan bahwa penggabungan string literal dapat dilakukan pada waktu kompilasi. Hapus saja
+
.sumber
std::literals::string_literals
, bukan konsep UDL.Untuk menawarkan solusi yang lebih one-line-ish: Sebuah fungsi
concat
dapat diimplementasikan untuk mengurangi solusi berbasis stringstream "klasik" menjadi satu pernyataan . Ini didasarkan pada template variadic dan penerusan yang sempurna.Pemakaian:
Penerapan:
sumber
Di C ++ 20 Anda dapat melakukan:
Sampai saat itu Anda dapat melakukan hal yang sama dengan perpustakaan {fmt} :
Penafian : Saya penulis {fmt}.
sumber
boost :: format
atau std :: stringstream
sumber
Masalah sebenarnya adalah bahwa menggabungkan string literal dengan
+
gagal dalam C ++:Dalam C ++ (juga dalam C), Anda menggabungkan string literal dengan menempatkannya tepat di sebelah satu sama lain:
Ini masuk akal, jika Anda menghasilkan kode di makro:
... makro sederhana yang dapat digunakan seperti ini
( demo langsung ... )
atau, jika Anda bersikeras untuk menggunakan
+
string literal (seperti yang disarankan oleh underscore_d ):Solusi lain menggabungkan string dan a
const char*
untuk setiap langkah penggabungansumber
sprintf
merupakan pilihan, tetapi ada juga std :: stringstream yang mencegah masalah dengan buffer yang berukuran terlalu kecil.sumber
Anda harus mendefinisikan operator + () untuk setiap tipe data yang ingin Anda hubungkan ke string, namun karena operator << ditentukan untuk sebagian besar tipe, Anda harus menggunakan std :: stringstream.
Sial, kalahkan 50 detik ...
sumber
std::string operator+(std::string s, int i){ return s+std::to_string(i); }
Jika Anda menuliskannya
+=
, tampilannya hampir sama dengan C #sumber
Seperti yang dikatakan orang lain, masalah utama dengan kode OP adalah bahwa operator
+
tidak terhubungconst char *
; itu bekerja dengan baikstd::string
.Berikut solusi lain yang menggunakan C ++ 11 lambdas dan
for_each
dan memungkinkan untuk menyediakanseparator
untuk memisahkan string:Pemakaian:
Tampaknya skala dengan baik (linear), setidaknya setelah tes cepat di komputer saya; inilah tes cepat yang saya tulis:
Hasil (milidetik):
sumber
Mungkin Anda menyukai solusi "Streamer" saya untuk benar-benar melakukannya dalam satu baris:
sumber
Inilah solusi satu-liner:
Meskipun agak jelek, saya pikir ini sebersih kucing Anda masuk C ++.
Kami melemparkan argumen pertama ke a
std::string
dan kemudian menggunakan urutan evaluasi (kiri ke kanan)operator+
untuk memastikan bahwa operan kirinya selalu astd::string
. Dengan cara ini, kami menggabungkan tombolstd::string
di sebelah kiri denganconst char *
operan di sebelah kanan dan mengembalikan yang lainstd::string
, memberikan efek.Catatan: ada beberapa pilihan untuk operan kanan, termasuk
const char *
,std::string
, danchar
.Terserah Anda untuk memutuskan apakah angka ajaib adalah 13 atau 6227020800.
sumber
Anda dapat menggunakan tajuk ini untuk hal ini: https://github.com/theypsilon/concat
Di bawah tenda Anda akan menggunakan std :: ostringstream.
sumber
Jika Anda bersedia menggunakan,
c++11
Anda dapat menggunakan string literal yang ditentukan pengguna dan menetapkan dua templat fungsi yang membebani operator plus untuk suatustd::string
objek dan objek lainnya. Satu-satunya perangkap adalah bukan untuk membebani operator plusstd::string
, jika tidak kompiler tidak tahu operator mana yang harus digunakan. Anda dapat melakukan ini dengan menggunakan templatstd::enable_if
daritype_traits
. Setelah itu string berperilaku seperti di Java atau C #. Lihat contoh implementasi saya untuk detailnya.Kode utama
File c_sharp_strings.hpp
Sertakan file header ini di semua tempat di mana Anda ingin memiliki string ini.
sumber
Sesuatu seperti ini bekerja untuk saya
sumber
Berdasarkan solusi di atas saya membuat kelas var_string untuk proyek saya untuk membuat hidup lebih mudah. Contoh:
Kelas itu sendiri:
Masih bertanya-tanya apakah akan ada sesuatu yang lebih baik di C ++?
sumber
Di c11:
ini memungkinkan Anda untuk membuat panggilan fungsi seperti ini:
akan mencetak: nomor pesan: 10
sumber
Anda juga dapat "memperluas" kelas string dan memilih operator yang Anda sukai (<<, &, |, dll ...)
Berikut adalah kode menggunakan operator << untuk menunjukkan tidak ada konflik dengan stream
catatan: jika Anda membatalkan komentar s1.reserve (30), hanya ada 3 permintaan operator baru () (1 untuk s1, 1 untuk s2, 1 untuk cadangan; sayangnya Anda tidak dapat memesan pada waktu konstruktor); tanpa cadangan, s1 harus meminta lebih banyak memori saat ia tumbuh, jadi itu tergantung pada faktor pertumbuhan implementasi kompiler Anda (milik saya tampaknya 1,5, 5 baru () memanggil dalam contoh ini)
sumber
Stringstream dengan makro preprokrosesor sederhana menggunakan fungsi lambda tampak bagus:
lalu
sumber
Ini bekerja untuk saya:
Keluaran:
sumber
const
atau (jika penyimpanan nol adalah persyaratan) sebuahenum
akan menjadi?Sudahkah Anda mencoba menghindari + =? alih-alih gunakan var = var + ... itu berhasil untuk saya.
sumber
#include <iostream.h> // string
#include <system.hpp> // ansiString