Bagaimana cara menggabungkan const/literal string di C?
I'm bekerja di C, dan aku harus menggabungkan beberapa hal.
Sekarang saya memiliki ini:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Sekarang jika anda memiliki pengalaman dalam C I'm yakin anda menyadari bahwa ini akan memberikan anda segmentasi kesalahan ketika anda mencoba untuk menjalankan hal itu. Jadi bagaimana cara mengatasi itu?
321
17
Dalam C, "strings" ada yang hanya sekadar
char
array. Oleh karena itu, anda dapat't langsung menggabungkannya dengan yang lain "strings".Anda dapat menggunakan
strcat
fungsi, yang menambahkan string yang ditunjukkan olehsrc
di akhir string yang ditunjukkan olehtujuan
:Berikut ini adalah sebuah contoh dari cplusplus.com:
Untuk parameter pertama, anda perlu menyediakan buffer tujuan itu sendiri. Tujuan penyangga harus array char buffer. E. g.:
char buffer[1024];
Pastikan bahwa parameter pertama yang memiliki cukup ruang untuk menyimpan apa yang anda're mencoba untuk menyalin ke dalamnya. Jika tersedia untuk anda, itu lebih aman untuk menggunakan fungsi-fungsi seperti:
strcpy_s
danstrcat_s
di mana anda secara eksplisit harus menentukan ukuran buffer tujuan.Note: Sebuah string literal tidak dapat digunakan sebagai penyangga, karena itu adalah konstan. Dengan demikian, anda selalu harus mengalokasikan array char untuk buffer.
Nilai kembali dari
strcat
hanya dapat diabaikan, itu hanya mengembalikan pointer sebagai disahkan sebagai argumen pertama. Hal ini ada untuk kenyamanan anda, dan memungkinkan anda untuk rantai panggilan ke satu baris kode:Sehingga masalah anda dapat diselesaikan sebagai berikut:
Hindari menggunakan
strcat
dalam kode C. Terbersih dan, yang paling penting, cara yang paling aman adalah dengan menggunakansnprintf
:Beberapa komentator mengangkat sebuah isu bahwa jumlah argumen yang mungkin tidak sesuai format string dan kode masih akan mengkompilasi, tapi kebanyakan kompiler sudah mengeluarkan peringatan jika hal ini terjadi.
Orang-orang, menggunakan strncpy(), strncat(), atau snprintf().
anda Melebihi ruang buffer akan sampah apa pun yang berikut dalam memori!
(Dan ingat untuk memungkinkan ruang untuk trailing null '\0' karakter!)
String juga dapat disambung pada waktu kompilasi.
Juga malloc dan realloc berguna jika anda don't tahu di depan waktu berapa banyak string yang bersambung.
Jangan lupa untuk menginisialisasi output buffer. Argumen pertama untuk strcat harus null terminated string dengan ruang tambahan yang dialokasikan untuk string yang dihasilkan:
Sebagai orang-orang yang menunjuk string penanganan banyak peningkatan. Jadi, anda mungkin ingin belajar bagaimana menggunakan C++ string perpustakaan bukan C-style string. Namun di sini adalah solusi yang murni C
Saya tidak yakin apakah itu benar/aman tapi sekarang aku tidak bisa menemukan cara yang lebih baik untuk melakukan hal ini dalam ANSI C.
Cara terbaik untuk melakukannya tanpa harus terbatas ukuran buffer adalah dengan menggunakan asprintf()
Itu adalah perilaku tidak terdefinisi untuk mencoba untuk memodifikasi string literal, yang adalah apa sesuatu seperti:
akan mencoba untuk melakukan. Ia akan mencoba untuk taktik pada
nama
string ke akhir dari string literal"Hello, "
, yang tidak didefinisikan dengan baik.Mencoba sesuatu ini. Mencapai apa yang anda tampaknya mencoba untuk melakukan:
Hal ini menciptakan daerah penyangga bahwa adalah diperbolehkan untuk dimodifikasi dan kemudian salinan kedua string literal dan teks lain untuk itu. Hanya berhati-hati dengan buffer overflows. Jika anda kontrol input data (atau periksa sebelum-tangan), it's baik-baik saja untuk menggunakan panjang tetap buffer seperti yang saya miliki.
Jika tidak, anda harus menggunakan strategi mitigasi seperti mengalokasikan cukup memori dari tumpukan untuk memastikan anda bisa mengatasinya. Dengan kata lain, sesuatu seperti:
Argumen pertama dari strcat() harus mampu menahan cukup ruang untuk menggabungkan string. Jadi mengalokasikan buffer dengan ruang yang cukup untuk menerima hasilnya.
strcat() akan menggabungkan kedua argumen dengan argumen pertama, dan menyimpan hasilnya dalam argumen pertama, kembali char* hanya ini argumen pertama, dan hanya untuk kenyamanan anda.
Anda tidak mendapatkan yang baru dialokasikan string dengan yang pertama dan kedua argumen bersambung, yang saya'd kira anda diharapkan didasarkan pada kode anda.
Anda dapat menulis fungsi sendiri yang melakukan hal yang sama sebagai
strcat()
tapi itu doesn't mengubah apa-apa:Jika kedua string bersama-sama lebih dari 1000 karakter, maka akan memotong string di 1000 karakter. Anda dapat mengubah nilai
MAX_STRING_LENGTH
sesuai dengan kebutuhan anda.Jika anda memiliki pengalaman di C, anda akan melihat bahwa string yang hanya char array dimana karakter terakhir adalah karakter null.
Sekarang ini cukup merepotkan karena anda harus menemukan karakter terakhir dalam rangka untuk menambahkan sesuatu.
strcat
akan melakukannya untuk anda.Jadi strcat pencarian melalui argumen pertama untuk karakter null. Maka akan ganti dengan argumen kedua's konten (sampai berakhir di nol).
Sekarang mari's pergi melalui kode anda:
Di sini anda menambahkan sesuatu untuk pointer ke teks "TEXT" (jenis "TEXT" const char*. Pointer.).
Yang biasanya tidak akan bekerja. Juga memodifikasi "TEXT" array tidak akan bekerja seperti ini biasanya ditempatkan di sebuah konstanta segmen.
Yang mungkin bekerja lebih baik, kecuali bahwa anda lagi mencoba untuk memodifikasi teks statis. strcat tidak mengalokasikan memori baru untuk hasilnya.
Saya akan mengusulkan untuk melakukan sesuatu seperti ini bukan:
Baca dokumentasi dari
sprintf
untuk memeriksa untuk itu's pilihan.Dan sekarang poin penting:
Memastikan bahwa penyangga yang memiliki cukup ruang untuk menyimpan teks DAN karakter null. Ada beberapa fungsi yang dapat membantu anda, misalnya, strncat dan versi khusus dari printf yang mengalokasikan buffer untuk anda. Tidak membuat ukuran buffer akan menyebabkan memori korupsi dan jarak jauh exploitasi bug.
Dengan asumsi anda memiliki char[fixed_size] daripada char, anda dapat menggunakan satu, kreatif makro untuk melakukan itu semua sekaligus dengan
<<cout<<seperti
pemesanan ("bukan %s yang terputus-putus %s\n", "dari", "printf gaya format"). Jika anda bekerja dengan sistem embedded, metode ini juga akan memungkinkan anda untuk meninggalkan malloc dan besar `printfkeluarga fungsi seperti
snprintf()` (hal Ini membuat dietlibc dari mengeluh tentang *printf juga)Anda mencoba untuk menyalin string ke sebuah alamat yang statis dialokasikan. Anda perlu untuk kucing ke dalam buffer.
Secara khusus:
...snip...
tujuan
...snip...
http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
Ada's contoh di sini juga.
Ini adalah solusi saya
tapi anda perlu menentukan berapa banyak string yang anda'kembali akan menyatukan
Mencoba sesuatu yang mirip dengan ini: