Bagaimana cara mengubah NSString menjadi std :: string?

94

Saya memiliki sebuah NSStringobjek dan ingin mengubahnya menjadi file std::string.

Bagaimana cara melakukan ini di Objective-C ++?

gabor
sumber
4
@rvalue bukan duplikat - hanya konversi kebalikan.
eric

Jawaban:

134
NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String]);

Sunting: Setelah beberapa tahun, izinkan saya memperluas jawaban ini. Seperti yang ditunjukkan dengan benar, Anda kemungkinan besar ingin menggunakan cStringUsingEncoding:dengan NSASCIIStringEncodingjika Anda akhirnya akan menggunakan std::string. Anda dapat menggunakan UTF-8 dengan normal std::strings, tetapi perlu diingat bahwa itu beroperasi pada byte dan bukan pada karakter atau bahkan grafem. Untuk "memulai" yang baik, lihat pertanyaan ini dan jawabannya .

Perhatikan juga, jika Anda memiliki string yang tidak dapat direpresentasikan sebagai ASCII tetapi Anda masih menginginkannya di dalam std::stringdan Anda tidak ingin karakter non-ASCII di sana, Anda dapat menggunakan dataUsingEncoding:allowLossyConversion:untuk mendapatkan NSDatarepresentasi dari string dengan ASCII yang dienkode dengan lossy konten, dan kemudian melemparkannya ke Andastd::string

JustSid
sumber
13
Hati-hati dalam pengkodean. Meskipun UTF-8 umumnya merupakan pilihan yang baik, jika API yang Anda gunakan mengharapkan, katakanlah, ASCII murni atau halaman kode sistem, Anda harus menggunakan -cStringUsingEncoding:sebagai gantinya. :)
Jonathan Grynspan
13
Ini adalah kebocoran memori jika Anda tidak menghapusnya, pointer yang dikembalikan bukan objek terhitung referensi Objective-C. Secara umum, Anda harus menghindari penggunaan operator new untuk std :: string.
SiimKallas
Ini seharusnya bukan jawaban yang diterima dan jelas bukan hal pertama yang harus dipertimbangkan saat melakukan konversi itu.
JBL
@JBL Setelah hanya 4 tahun dan beberapa minggu saya berkeliling untuk memperluas jawaban saya. Saya harap itu lebih bisa diterima sekarang.
JustSid
@JustSid Saya seharusnya menyatakan pendapat saya, tetapi masalah lainnya adalah penggunaan pointer secara default. Faktanya, seorang rekan kerja dengan latar belakang ObjC, tanpa pengetahuan C ++ menggunakannya, tanpa menghapus, berakhir dengan kebocoran memori. Dan lebih umum; wild news tidak disukai, dan a std::shared_ptratau std::unique_ptrharus lebih disukai.
JBL
50

Seperti yang disarankan Ynau di komentar, dalam kasus umum, akan lebih baik untuk menyimpan semuanya di tumpukan daripada di heap (menggunakan newmembuat string di heap), karenanya (dengan asumsi pengkodean UTF8):

NSString *foo = @"Foo";
std::string bar([foo UTF8String]);
Marco83
sumber
8

Seperti dicatat di philjordan.eu , bisa juga NSString adalah nil. Dalam kasus seperti itu, pemeran harus dilakukan seperti ini:

// CATATAN: jika foo nil ini akan menghasilkan string C ++ kosong

// alih-alih mendereferensi penunjuk NULL dari UTF8String.

Ini akan membawa Anda pada pertobatan seperti itu:

NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
Bruno Bieri
sumber
1
Ini sangat berguna. Khawatir melihat hampir semua orang mengabaikannya. Kalian akan jatuh di NIL.
P i