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?

Jonathan Prior
sumber

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.

Jesse Beder
sumber
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);
Eugene
sumber
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
Atul
sumber
28

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

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

Paul
sumber
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();
James Thompson
sumber
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;

sumber
6
char* data;
stringstream myStreamString;
myStreamString << data;
string myString = myStreamString.str();
cout << myString << endl;
Hadir
sumber
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;
Erik van Velzen
sumber
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!

pengguna1564286
sumber
0
char* data;
std::string myString(data);
Daniel A. White
sumber
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';
Vern Jensen
sumber
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