Dokumentasinya benar. Gunakan c_str()
jika Anda ingin string diakhiri null.
Jika pelaksana yang ingin mengimplementasikan data()
dalam hal c_str()
Anda tidak perlu khawatir, tetap gunakan data()
jika Anda tidak ingin string diakhiri null, dalam beberapa implementasi mungkin berkinerja lebih baik daripada c_str ().
string tidak harus terdiri dari data karakter, string dapat disusun dengan elemen jenis apa pun. Dalam kasus data()
tersebut lebih berarti. c_str()
menurut saya hanya sangat berguna jika elemen string Anda berbasis karakter.
Ekstra : Dalam C ++ 11 dan seterusnya, kedua fungsi tersebut harus sama. yaitu data
sekarang harus diakhiri dengan null. Menurut cppreference : "Array yang dikembalikan adalah null-terminated, yaitu data () dan c_str () melakukan fungsi yang sama."
.data()
, sehingga tidak lagi setara untuk string non-konstan.Di C ++ 11 / C ++ 0x ,
data()
danc_str()
tidak lagi berbeda. Dan dengan demikiandata()
diharuskan memiliki penghentian nol di akhir juga.sumber
std::string
pengalokasian ekstrachar
untuk trailing'\0'
. Jika Anda melakukannyastd::string s("\0");
, keduanyas.data()[0]
dans.data()[1]
dijamin akan bernilai 0.Meskipun Anda telah melihat bahwa mereka melakukan hal yang sama, atau bahwa .data () memanggil .c_str (), tidaklah benar untuk mengasumsikan bahwa ini akan menjadi kasus untuk kompiler lain. Mungkin juga kompilator Anda akan berubah dengan rilis mendatang.
2 alasan untuk menggunakan std :: string:
std :: string dapat digunakan untuk teks dan data biner arbitrer.
Anda harus menggunakan metode .c_str () saat Anda menggunakan string Anda sebagai contoh 1.
Anda harus menggunakan metode .data () saat Anda menggunakan string sebagai contoh 2. Bukan karena berbahaya untuk menggunakan .c_str () dalam kasus ini, tetapi karena lebih eksplisit bahwa Anda bekerja dengan data biner untuk ditinjau orang lain kode Anda.
Kemungkinan jebakan dengan menggunakan .data ()
Kode berikut salah dan dapat menyebabkan segfault dalam program Anda:
Mengapa umum bagi pelaksana untuk membuat .data () dan .c_str () melakukan hal yang sama?
Karena lebih efisien melakukannya. Satu-satunya cara untuk membuat .data () mengembalikan sesuatu yang tidak diakhiri null, adalah dengan membuat .c_str () atau .data () menyalin buffer internalnya, atau hanya menggunakan 2 buffer. Memiliki satu buffer diakhiri null selalu berarti bahwa Anda selalu dapat menggunakan hanya satu buffer internal saat mengimplementasikan std :: string.
sumber
Itu sudah dijawab, beberapa catatan tentang tujuan: Kebebasan implementasi.
std::string
operasi - misalnya iterasi, penggabungan, dan mutasi elemen - tidak memerlukan terminator nol. Kecuali Anda meneruskanstring
ke fungsi yang mengharapkan string diakhiri nol, itu bisa dihilangkan.Ini akan memungkinkan implementasi memiliki substring yang berbagi data string aktual: secara
string::substr
internal dapat menyimpan referensi ke data string bersama, dan rentang awal / akhir, menghindari salinan (dan alokasi tambahan) dari data string aktual. Implementasinya akan menunda salinan sampai Anda memanggil c_str atau mengubah salah satu string. Salinan tidak akan pernah dibuat jika strign yang terlibat baru saja dibaca.(implementasi copy-on-write tidak terlalu menyenangkan di lingkungan multithread, ditambah penghematan alokasi / memori yang khas tidak sebanding dengan kode yang lebih kompleks saat ini, jadi jarang dilakukan).
Demikian pula,
string::data
memungkinkan representasi internal yang berbeda, misalnya tali (daftar segmen tali yang terhubung). Ini dapat meningkatkan operasi penyisipan / penggantian secara signifikan. sekali lagi, daftar segmen harus diciutkan menjadi satu segmen saat Anda memanggilc_str
ataudata
.sumber
Kutipan dari
ANSI ISO IEC 14882 2003
(C ++ 03 Standard):sumber
Semua perintah sebelumnya adalah konsistensi, tetapi saya juga ingin menambahkan bahwa mulai c ++ 17, str.data () mengembalikan sebuah char * daripada const char *
sumber
const
dannon-const
kelebihan beban tersedia sejak C ++ 17.