Saya ingin mengonversi std :: string menjadi char * atau char [] .
std::string str = "string";
char* chr = str;
Hasil dalam: "kesalahan: tidak dapat mengkonversi 'std :: string' ke 'char' ..." .
Metode apa yang tersedia untuk melakukan ini?
Itu tidak akan secara otomatis mengkonversi (terima kasih Tuhan). Anda harus menggunakan metode ini c_str()
untuk mendapatkan versi string C.
std::string str = "string";
const char *cstr = str.c_str();
Perhatikan bahwa ia mengembalikan a const char *
; Anda tidak diizinkan mengubah string C-style yang dikembalikan oleh c_str()
. Jika Anda ingin memprosesnya, Anda harus menyalinnya terlebih dahulu:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Atau di C ++ modern:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
c_str
kegilaan ini sepenuhnya.vector
diciptakan tepat sebagai pembungkus untuk array dinamis, jadi tidak menggunakannya sepertinya peluang yang terlewatkan, dan yang melanggar semangat C ++ paling buruk.std::string
akan secara otomatis mengkonversi) dan kemudian saya menjelaskan apa yang harus dia gunakan, dengan contoh kode pendek. Berpikir ke depan Saya juga menjelaskan beberapa efek samping dari penggunaan fungsi ini, di antaranya adalah Anda tidak boleh mengedit string yang dikembalikan olehc_str()
. Anda keliru melihat contoh singkat saya sebagai kode pemecahan masalah yang nyata, padahal bukan.std::vector<char>
).Lebih detail di sini , dan di sini tetapi Anda dapat menggunakan
sumber
Jika saya memerlukan salinan mentah yang dapat diubah dari isi string c ++, maka saya akan melakukan ini:
dan kemudian:
Jadi mengapa saya tidak bermain-main dengan std :: vector atau baru [] seperti orang lain? Karena ketika saya membutuhkan string char * raw C-style yang dapat diubah, maka karena saya ingin memanggil kode C yang mengubah string dan kode C mengalokasikan barang dengan bebas () dan mengalokasikan dengan malloc () (strdup menggunakan malloc) . Jadi jika saya lulus string baku saya untuk beberapa fungsi X ditulis dalam C itu mungkin memiliki kendala pada argumen itu yang telah untuk dialokasikan di heap (misalnya jika fungsi mungkin ingin menelepon realloc pada parameter). Tetapi sangat tidak mungkin bahwa itu akan mengharapkan argumen dialokasikan dengan (beberapa pengguna-didefinisikan ulang) baru []!
sumber
strdup
.(Jawaban ini hanya berlaku untuk C ++ 98.)
Tolong, jangan gunakan mentah
char*
.sumber
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, tanpa menetapkan pointer char untuk sementara?std::basic_string<>::c_str()
valid hinggastring
diubah atau dimusnahkan. Ini juga menyiratkan bahwa ia mengembalikan nilai yang sama pada panggilan berikutnya selamastring
tidak diubah.vector
cara ini. Dan jika seseorang menulis kode pengecualian-aman tanpa mekanisme RAII (yaitu, menggunakan pointer mentah), kompleksitas kode akan jauh lebih tinggi daripada ini satu-liner sederhana.vector
memiliki overhead dan kompleksitas yang sangat besar. Jika kebutuhan Anda adalah bahwa Anda memiliki array char yang bisa berubah , maka sebenarnya vektor karakter adalah pembungkus C ++ yang ideal. Jika kebutuhan Anda sebenarnya hanya memanggil pointer const-char, maka cukup gunakanc_str()
dan Anda selesai.Jika Anda hanya ingin string gaya-C yang mewakili konten yang sama:
Jika Anda ingin string gaya-C dengan konten baru , satu cara (mengingat Anda tidak tahu ukuran string pada waktu kompilasi) adalah alokasi dinamis:
Jangan lupa
delete[]
nanti.Jika Anda menginginkan array yang dialokasikan secara statis, maka array dengan panjang terbatas:
std::string
tidak secara implisit mengkonversi ke jenis ini untuk alasan sederhana yang perlu melakukan ini biasanya bau desain. Pastikan Anda benar - benar membutuhkannya.Jika Anda benar - benar membutuhkan
char*
, cara terbaik mungkin:sumber
&str.front(), &str.back()
(yang tidak ada dalam C ++ 03) bukannya yang lebih umumstr.begin()
danstr.end()
?str.begin()
, atau bahkanstd::begin(str)
, seperti iterator? Saya tidak percayastring
memiliki kewajiban untuk berada di memori yang berdekatan sepertivector
, atau bukan?&back() + 1
, bukan&back()
Ini akan lebih baik sebagai komentar pada jawaban bobobobo, tetapi saya tidak memiliki perwakilan untuk itu. Ini mencapai hal yang sama tetapi dengan praktik yang lebih baik.
Meskipun jawaban lain yang berguna, jika Anda merasa perlu untuk mengkonversi
std::string
kechar*
eksplisit tanpa const,const_cast
adalah teman Anda.Perhatikan bahwa ini tidak akan memberi Anda salinan data; itu akan memberi Anda pointer ke string. Jadi, jika Anda memodifikasi elemen
chr
, Anda akan memodifikasistr
.sumber
Dengan asumsi Anda hanya perlu string gaya-C untuk lulus sebagai input:
sumber
Agar benar-benar bertele-tele, Anda tidak dapat "mengubah string std :: menjadi tipe data char * atau char []."
Seperti yang ditunjukkan oleh jawaban lain, Anda dapat menyalin konten std :: string ke array char, atau membuat const char * ke konten std :: string sehingga Anda dapat mengaksesnya dalam "gaya C" .
Jika Anda mencoba mengubah konten std :: string, tipe std :: string memiliki semua metode untuk melakukan apa pun yang mungkin perlu Anda lakukan untuk itu.
Jika Anda mencoba meneruskannya ke beberapa fungsi yang mengambil char *, ada std :: string :: c_str ().
sumber
Ini adalah satu lagi versi yang lebih kuat dari
Protocol Buffer
sumber
if (str[str.length()-1] != 0) str.push_back(0)
Konversi dalam gaya OOP
converter.hpp
converter.cpp
pemakaian
sumber
Demi kelengkapan, jangan lupa
std::string::copy()
.std::string::copy()
tidak NUL berakhir. Jika Anda perlu memastikan terminator NUL untuk digunakan dalam fungsi string C:sumber
Anda bisa membuatnya menggunakan iterator.
Semoga berhasil.
sumber
Versi aman dari jawaban orlp char * menggunakan unique_ptr:
sumber
Untuk mendapatkan a
const char *
daristd::string
penggunaanc_str()
fungsi anggota:Untuk mendapatkan non-const
char *
daristd::string
Anda dapat menggunakandata()
fungsi anggota yang mengembalikan pointer non-const sejak C ++ 17:Untuk versi bahasa yang lebih lama, Anda bisa menggunakan konstruksi rentang untuk menyalin string ke dalam vektor dari mana pointer non-const dapat diperoleh:
Tetapi berhati-hatilah karena ini tidak akan membiarkan Anda memodifikasi string yang terkandung
str
, hanya data salinan yang dapat diubah dengan cara ini. Perhatikan bahwa ini sangat penting dalam versi bahasa yang lebih lama untuk digunakan dic_str()
sini karena pada saatstd::string
itu tidak dijamin akan dibatalkan nol sampaic_str()
dipanggil.sumber
sumber
Atau, Anda dapat menggunakan vektor untuk mendapatkan karakter * yang dapat ditulisi seperti yang ditunjukkan di bawah ini;
sumber
Ini juga akan berfungsi
sumber