konversikan char * menjadi std :: string


262

Saya perlu menggunakan std::stringuntuk menyimpan data yang diambil oleh fgets(). Untuk melakukan ini, saya perlu mengubah nilai char*kembali dari fgets()menjadi std::stringmenyimpan dalam array. Bagaimana ini bisa dilakukan?

Jawaban:


376

std::string memiliki konstruktor untuk ini:

const char *s = "Hello, World!";
std::string str(s);

Perhatikan bahwa ini membangun salinan dalam daftar karakter di sdan stidak boleh nullptr, atau perilaku tidak terdefinisi.


6
apa yang akan terjadi jika itu?
Carson Myers

14
Standar mengatakan bahwa parameter konstruktor "tidak akan menjadi pointer nol" - itu tidak menentukan bahwa ada pengecualian yang dilemparkan.

24
Apakah itu salinan dangkal atau dalam?

4
@pushkin No strhanyalah nama variabel. Bisa apa saja: S, abc, l, I, strHelloWorld. Jelas beberapa pilihan lebih baik daripada yang lain. Tetapi untuk contoh strini cukup dapat diterima.
Disillusioned

10
@ Madhatter itu adalah salinan yang dalam. Alokasi pointer akan tetap, dan string akan membuat sendiri alokasi baru.
moodboom

127

Jika Anda sudah tahu ukuran char *, gunakan ini sebagai gantinya

char* data = ...;
int size = ...;
std::string myString(data, size);

Ini tidak menggunakan strlen.

EDIT: Jika variabel string sudah ada, gunakan assign ():

std::string myString;
char* data = ...;
int size = ...;
myString.assign(data, size);

1
Semacam pertanyaan sampingan, Eugene. Jika data tidak terisi hingga nanti dalam rutinitas, bagaimana Anda menginisialisasi myString? Apakah Anda hanya mendeklarasikan variabel myString saat diisi?
IcedDante

2
int size = strlen (data);
Vlad

@vlad: idenya adalah Anda mengetahui ukuran dari beberapa sumber lain dan / atau data bukan C-string (telah menyematkan nol atau tidak berakhir dengan nol). Jika Anda memiliki C-string, Anda cukup melakukan myString = data; itu akan berjalan strlen atau setara untuk Anda.
Eugene

1
@huseyintugrulbuyukisik Anda masih harus membuang memori asli dengan benar - std :: string akan menyalin byte, tidak mengambil kepemilikan.
Eugene

2
@ZackLee itu akan mengalokasikan memori baru untuk byte dan menyalinnya semua di sana, sehingga sedalam yang didapat. Jika Anda ingin potensi salinan dangkal, Anda harus menyalin satu std :: string ke yang lain. Maka beberapa implementasi bisa melakukan salinan dangkal saya pikir.
Eugene

30

Sebagian besar jawaban berbicara tentang membangun std::string .

Jika sudah dibangun, cukup gunakan operator penugasan .

std::string oString;
char* pStr;

... // Here allocate and get character string (e.g. using fgets as you mentioned)

oString = pStr; // This is it! It copies contents from pStr to oString

28

Saya perlu menggunakan std :: string untuk menyimpan data yang diambil oleh fgets ().

Mengapa menggunakan fgets()saat Anda memprogram C ++? Mengapa tidak std::getline()?


18

Kirimkan melalui konstruktor:

const char* dat = "my string!";
std::string my_string( dat );

Anda dapat menggunakan fungsi string.c_str () untuk menuju ke arah lain:

std::string my_string("testing!");
const char* dat = my_string.c_str();

3
c_str()kembaliconst char*
Steve Jessop

1
benar, Anda tidak dapat (tidak boleh) memodifikasi data dalam std :: string via c_str (). Jika Anda berniat untuk mengubah data, maka string c dari c_str () harus memcpy'd
Carson Myers

11
const char* charPointer = "Hello, World!\n";
std::string strFromChar;
strFromChar.append(charPointer);
std::cout<<strFromChar<<std::endl;

6
char* data;
stringstream myStreamString;
myStreamString << data;
string myString = myStreamString.str();
cout << myString << endl;

5

Saya ingin menyebutkan metode baru yang menggunakan literal yang ditentukan pengguna s. Ini bukan hal baru, tetapi akan lebih umum karena ditambahkan di Perpustakaan Standar C ++ 14.

Sangat berlebihan dalam kasus umum:

string mystring = "your string here"s;

Tetapi ini memungkinkan Anda untuk menggunakan otomatis, juga dengan string lebar:

auto mystring = U"your UTF-32 string here"s;

Dan di sinilah ia benar-benar bersinar:

string suffix;
cin >> suffix;
string mystring = "mystring"s + suffix;

2

Saya baru saja berjuang dengan MSVC2005 untuk menggunakan std::string(char*)konstruktor seperti jawaban berperingkat teratas. Seperti yang saya lihat varian ini terdaftar sebagai # 4 di http://en.cppreference.com/w/cpp/string/basic_string/basic_string yang selalu dipercaya , saya pikir bahkan kompiler lama menawarkan ini.

Butuh waktu lama bagi saya untuk menyadari bahwa konstruktor absolut ini menolak untuk cocok (unsigned char*)sebagai argumen! Saya mendapat pesan kesalahan yang tidak dapat dipahami ini tentang kegagalan untuk mencocokkan dengan std::stringjenis argumen, yang jelas bukan yang saya tuju. Hanya melempar argumen dengan std::string((char*)ucharPtr)memecahkan masalah saya ... ya!


0
char* data;
std::string myString(data);

9
Ini akan menghasilkan perilaku yang tidak terdefinisi.

1
Dengan hanya dua baris ini, datatetap tidak diinisialisasi (kosong).
heltonbiker

1
Tanpa "panjang" sebenarnya dari penunjuk yang diberikan, kode ini dapat menyebabkan data hilang, std :: string Anda akan "lebih pendek" dari karakter asli *
Andiana

0

Tidak yakin mengapa tidak ada orang selain Erik yang menyebutkan ini, tetapi menurut halaman ini , operator penugasan berfungsi dengan baik. Tidak perlu menggunakan konstruktor, .assign (), atau .append ().

std::string mystring;
mystring = "This is a test!";   // Assign C string to std:string directly
std::cout << mystring << '\n';

1
Tampaknya berfungsi secara fungsional, tetapi ketika saya melakukan ini saya mulai mendapatkan masalah dengan Valgrind melaporkan blok yang dapat dijangkau di akhir program, yang berasal dari bagian "baru" dari =(dan +=). Sepertinya tidak terjadi dengan literal seperti ini, tetapi hanya dengan char*hal - hal. Masalah apakah laporan tersebut benar - benar bocor dibahas di sini . Tetapi jika saya mengubah tugas untuk destString = std::string(srcCharPtr);kebocoran valgrind laporan hilang. YMMV.
HostileFork bilang jangan percaya

Komentar HostileFork mungkin membuat Anda percaya bahwa membuat string dari char * (seperti dari fgets) akan membuat std :: string mengelola masa pakai memori ini. Namun ini bukan masalahnya. Lihat standar 21.4.2.7 dan .9 Constructs an object of class basic_string and determines its initial string value from the array. Dikatakan nilai dan tidak ada tentang kepemilikan buffer atau pointer.
Erik van Velzen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.