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?
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?
Jawaban:
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);
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 oleh c_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
string str = "some string" ;
char *cstr = &str[0];
Jika saya memerlukan salinan mentah yang dapat diubah dari isi string c ++, maka saya akan melakukan ini:
std::string str = "string";
char* chr = strdup(str.c_str());
dan kemudian:
free(chr);
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 []!
strdup
.
(Jawaban ini hanya berlaku untuk C ++ 98.)
Tolong, jangan gunakan mentah char*
.
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, tanpa menetapkan pointer char untuk sementara?
std::basic_string<>::c_str()
valid hingga string
diubah atau dimusnahkan. Ini juga menyiratkan bahwa ia mengembalikan nilai yang sama pada panggilan berikutnya selama string
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 gunakan c_str()
dan Anda selesai.
Jika Anda hanya ingin string gaya-C yang mewakili konten yang sama:
char const* ca = str.c_str();
Jika Anda ingin string gaya-C dengan konten baru , satu cara (mengingat Anda tidak tahu ukuran string pada waktu kompilasi) adalah alokasi dinamis:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
Jangan lupa delete[]
nanti.
Jika Anda menginginkan array yang dialokasikan secara statis, maka array dengan panjang terbatas:
size_t const MAX = 80; // maximum number of chars
char ca[MAX] = {};
std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
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:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
&str.front(), &str.back()
(yang tidak ada dalam C ++ 03) bukannya yang lebih umum str.begin()
dan str.end()
?
str.begin()
, atau bahkan std::begin(str)
, seperti iterator? Saya tidak percaya string
memiliki kewajiban untuk berada di memori yang berdekatan seperti vector
, 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
ke char*
eksplisit tanpa const, const_cast
adalah teman Anda.
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
Perhatikan bahwa ini tidak akan memberi Anda salinan data; itu akan memberi Anda pointer ke string. Jadi, jika Anda memodifikasi elemen chr
, Anda akan memodifikasi str
.
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 ().
Ini adalah satu lagi versi yang lebih kuat dari Protocol Buffer
char* string_as_array(string* str)
{
return str->empty() ? NULL : &*str->begin();
}
// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
if (str[str.length()-1] != 0) str.push_back(0)
Konversi dalam gaya OOP
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
pemakaian
StringConverter::strToChar("converted string")
Demi kelengkapan, jangan lupa std::string::copy()
.
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy()
tidak NUL berakhir. Jika Anda perlu memastikan terminator NUL untuk digunakan dalam fungsi string C:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
Untuk mendapatkan a const char *
dari std::string
penggunaan c_str()
fungsi anggota:
std::string str = "string";
const char* chr = str.c_str();
Untuk mendapatkan non-const char *
dari std::string
Anda dapat menggunakan data()
fungsi anggota yang mengembalikan pointer non-const sejak C ++ 17:
std::string str = "string";
char* chr = str.data();
Untuk versi bahasa yang lebih lama, Anda bisa menggunakan konstruksi rentang untuk menyalin string ke dalam vektor dari mana pointer non-const dapat diperoleh:
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
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 di c_str()
sini karena pada saat std::string
itu tidak dijamin akan dibatalkan nol sampai c_str()
dipanggil.
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
Atau, Anda dapat menggunakan vektor untuk mendapatkan karakter * yang dapat ditulisi seperti yang ditunjukkan di bawah ini;
//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0');
char* cstring = &writable[0] //or &*writable.begin ()
//Goodluck
Ini juga akan berfungsi
std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;
c_str
kegilaan ini sepenuhnya.