Bagaimana cara mengubah std :: string ke NSString?

97

Hai, Saya mencoba mengubah standar std::stringmenjadiNSString tetapi saya tidak terlalu beruntung.

Saya dapat berhasil mengkonversi dari a NSStringke a std::stringdengan kode berikut

NSString *realm = @"Hollywood";
std::string REALM = [realm cStringUsingEncoding:[NSString defaultCStringEncoding]];

Namun saya mendapatkan kesalahan waktu kompilasi ketika saya mencoba yang berikut ini

NSString *errorMessage = [NSString stringWithCString:REALM encoding:[NSString defaultCStringEncoding]];

Kesalahan yang saya dapatkan adalah

Cannot convert 'std::string' to 'const char*' in argument passing

Apakah saya melewatkan sesuatu di sini?

Terima kasih sebelumnya.

Anthony McCormick
sumber
4
Ini pasti salah ketik, tetapi Anda kehilangan '@' untuk literal string di 'NSString * realm = "Hollywood";' baris.
Vladimir

Jawaban:

111

Dapatkan c-string dari std :: string untuk konversi:

NSString *errorMessage = [NSString stringWithCString:REALM.c_str() 
                                   encoding:[NSString defaultCStringEncoding]];
Vladimir
sumber
Tampaknya ini bukan jawaban yang baik, seperti yang dikatakan dalam dokumentasi: / * Pengkodean yang bergantung pada pengguna yang nilainya berasal dari bahasa default pengguna dan kemungkinan faktor lain. Penggunaan enkode ini terkadang diperlukan saat menafsirkan dokumen pengguna dengan enkode yang tidak diketahui, jika tidak ada petunjuk lain. Pengkodean ini harus jarang digunakan, jika sama sekali. Perhatikan bahwa beberapa nilai potensial di sini mungkin menghasilkan konversi encoding yang tidak terduga bahkan dari konten NSString yang cukup langsung --- misalnya, karakter tanda baca dengan encoding dua arah. * /
cyrilchampier
30
[NSString stringWithUTF8String: mystring.c_str ()] tampaknya lebih tepat, karena std :: string lebih mungkin berasal dari kode Anda sendiri, yang kemungkinan besar ada di UTF8.
cyrilchampier
Apakah kalian tahu mengapa di sini ( developer.apple.com/documentation/foundation/nsstring/… ) dikatakan "Objek yang dikembalikan mungkin berbeda dari penerima asli"? Apa artinya ini dan bagaimana kita tahu jika itu berbeda?
isJulian00
@ cyrilchapier bagaimana jika file .mm kami mengatakan "tidak ada pengkodean khusus yang ditentukan"?
isJulian00
53

Pertama, Anda harus menggunakan Objective-C ++ untuk bekerja sekecil apa pun; cara termudah untuk memastikannya adalah mengganti nama semua *.mfile Anda menjadi*.mm

Sejauh ini, cara manual yang paling berguna (tidak usang) untuk memasukkan C ++ std::stringke dalam NSStringadalah dengan:

std::string param; // <-- input
NSString* result = [NSString stringWithUTF8String:param.c_str()];
NSString* alternative = [[NSString alloc] initWithUTF8String:param.c_str()];

Ini akan bekerja dalam banyak kasus - dan jika Anda tidak melakukan deteksi dan konversi pengkodean khusus, UTF-8 akan memberi Anda hasil yang baik karena karakter non-latin 'hanya berfungsi'.

Namun, jika Anda membuat aplikasi yang lebih besar, atau Anda bukan satu-satunya yang mengerjakannya - Anda mungkin menginginkan sesuatu yang lebih mudah diterapkan.

Diadaptasi dari arsip milis cocoa-dev

@interface NSString (cppstring_additions)
+(NSString*) stringWithwstring:(const std::wstring&)string;
+(NSString*) stringWithstring:(const std::string&)string;
-(std::wstring) getwstring;
-(std::string) getstring;
@end

@implementation NSString (cppstring_additions)

#if TARGET_RT_BIG_ENDIAN
const NSStringEncoding kEncoding_wchar_t = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32BE);
#else
const NSStringEncoding kEncoding_wchar_t = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE);
#endif

+(NSString*) stringWithwstring:(const std::wstring&)ws
{
    char* data = (char*)ws.data();
    unsigned size = ws.size() * sizeof(wchar_t);

    NSString* result = [[NSString alloc] initWithBytes:data length:size encoding:kEncoding_wchar_t];
    return result;
}
+(NSString*) stringWithstring:(const std::string&)s
{
    NSString* result = [[NSString alloc] initWithUTF8String:s.c_str()];
    return result;
}

-(std::wstring) getwstring
{
    NSData* asData = [self dataUsingEncoding:kEncoding_wchar_t];
    return std::wstring((wchar_t*)[asData bytes], [asData length] / sizeof(wchar_t));
}
-(std::string) getstring
{
    return [self UTF8String];
}

@end

Dengan itu di tempat (dan dengan tepat #import) Anda sekarang dapat:

NSString* result = [NSString stringWithstring:param];
string convertedBack = [result getstring];

Dan hal yang sama untuk std::wstring, yang lebih dari sekadar berguna.

rvalue
sumber
1
Ini rad dan saya telah menggunakannya di beberapa proyek iphone. Satu hal yang saya perhatikan adalah jika saya menjalankan kerangka pengujian unit Apple dan saya menguji pustaka yang menggunakan metode ini, saya harus menyertakan file yang berisi metode konversi string sebagai salah satu "Sumber Kompilasi" dalam "Fase Build" untuk tes unit. Aneh.
David
1
Ya, pengujian unit pada dasarnya adalah program kecilnya sendiri, dan perlu memiliki akses ke kode yang sama. Juga, pujian untuk benar-benar menulis tes ;-)
rvalue
1
Apakah kalian tahu mengapa di sini ( developer.apple.com/documentation/foundation/nsstring/… ) dikatakan "Objek yang dikembalikan mungkin berbeda dari penerima asli"? Apa artinya ini dan bagaimana kita tahu jika itu berbeda?
isJulian00
1
@izzyMachado bahasa semacam itu dalam dokumen biasanya berarti mereka memiliki "hak" berdasarkan kontrak antarmuka untuk mengurai, membersihkan, atau mengkanonikalisasi string input. yaitu mungkin bukan perjalanan ==bolak-balik dan masih membandingkan melainkan menjadi representasi "terdekat" atau "terbaik" yang dapat mereka buat. Penerima dalam hal ini adalah NSStringimplementasi kelas, dan nilai yang dikembalikan bukanlah objek Objective-C, jadi mereka mungkin juga menutupinya dengan beberapa bahasa standar.
nilai p
Tahukah Anda mengapa ini masih berfungsi ketika kita menggunakan initWithUTF8String dan string menyertakan karakter non utf8, bagaimana ia masih dapat menggunakan string (jika mint UTF-8) dan mencetaknya setelah menjadi NSString?
isJulian00
21
NSString* mystring = [NSString stringWithUTF8String:stdstring.c_str()];
John Bowers
sumber
apakah ini membuat NSString UTF8? atau pengkodean apa yang akan dilakukan NSString?
isJulian00
14

Apple sekarang memiliki cara baru yang mereka inginkan untuk Anda lakukan konversi ini. Di XCode7, saya menggunakan opsi Edit> Convert> To Modern Objective C Syntax ... untuk mengetahuinya. Ini menggunakan simbol singkatan @.

std::string sCPPString = "Hello World!";
NSString *sAppleString = @(sCPPString.c_str());
Volomike
sumber
3

Saya juga menemukan bahwa:

NSString *nsString = [NSString stringWithFormat:@"%s",standardString];

Bekerja seperti juara.

BadPirate
sumber
3
Itu sangat tidak aman & tidak dijamin berhasil. standardString jika std :: string, adalah objek C ++. Objek C ++ tidak aman untuk diteruskan ke fungsi variadic (template variadic memecahkan masalah ini di C ++ 11). Jika berhasil, itu kebetulan & hampir setiap kompiler akan paling tidak memperingatkan Anda untuk tidak melakukan ini (jika ini bukan kesalahan untuk memulai).
Vitali
3

Berikut cuplikan kode / contoh:

string str_simple = "HELLO WORLD";

//string to NSString
NSString *stringinObjC = [NSString stringWithCString:str_simple.c_str()
                                encoding:[NSString defaultCStringEncoding]];            
NSLog(stringinObjC);
Deepak Kumar
sumber