Wie konvertiere ich std :: string in NSString?


97

Hallo, ich versuche einen Standard std::stringin einen umzuwandeln, NSStringaber ich habe nicht viel Glück.

Ich kann mit dem folgenden Code erfolgreich von a NSStringnach a konvertierenstd::string

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

Ich erhalte jedoch einen Fehler bei der Kompilierung, wenn ich Folgendes versuche

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

Der Fehler, den ich bekomme, ist

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

Vermisse ich hier etwas?

Danke im Voraus.


4
Es muss ein Tippfehler sein, aber in 'NSString * Realm = "Hollywood" fehlt' @ 'für das String-Literal.' Linie.
Vladimir

Antworten:


111

Holen Sie sich c-string aus std :: string zur Konvertierung:

NSString *errorMessage = [NSString stringWithCString:REALM.c_str() 
                                   encoding:[NSString defaultCStringEncoding]];

Dies scheint keine gute Antwort zu sein, da in der Dokumentation Folgendes angegeben ist: / * Benutzerabhängige Codierung, deren Wert von der Standardsprache des Benutzers und möglicherweise anderen Faktoren abgeleitet wird. Die Verwendung dieser Codierung kann manchmal erforderlich sein, wenn Benutzerdokumente mit unbekannten Codierungen interpretiert werden, wenn keine anderen Hinweise vorliegen. Diese Codierung sollte, wenn überhaupt, selten verwendet werden. Beachten Sie, dass einige potenzielle Werte hier zu unerwarteten Codierungskonvertierungen von selbst recht einfachen NSString-Inhalten führen können, z. B. Interpunktionszeichen mit einer bidirektionalen Codierung. * /
Cyrilchampier

30
[NSString stringWithUTF8String: mystring.c_str ()] scheint angemessener zu sein, da der std :: string eher aus Ihrem eigenen Code stammt, der wahrscheinlich in UTF8 enthalten ist.
Cyrilchampier

Wissen Sie, warum hier ( developer.apple.com/documentation/foundation/nsstring/… ) steht "Das zurückgegebene Objekt kann sich vom ursprünglichen Empfänger unterscheiden"? Was bedeutet das und wie würden wir wissen, ob es anders ist?
isJulian00

@cyrilchapier Was ist, wenn in unserer MM-Datei "Keine spezifische Codierung angegeben" steht?
isJulian00

53

Erstens müssen Sie Objective-C ++ verwenden, damit dies im geringsten funktioniert. Der einfachste Weg, um sicherzustellen, dass alle Ihre *.mDateien in umbenannt werden*.mm

Die bei weitem am besten verwendbare (nicht veraltete) manuelle Methode, um ein C ++ std::stringin ein C ++ zu bringen, NSStringist:

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

Dies funktioniert in den meisten Fällen - und wenn Sie keine spezifische Codierungserkennung und -konvertierung durchführen, liefert UTF-8 ein gutes Ergebnis, wenn nicht-lateinische Zeichen "nur funktionieren".

Wenn Sie jedoch eine größere App erstellen oder nicht die einzige sind, die daran arbeitet, möchten Sie wahrscheinlich etwas, das einfacher anzuwenden ist.

Angepasst aus den Archiven der Cocoa-Dev-Mailinglisten

@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

Mit diesem In-Place (und entsprechend #importbearbeitet) können Sie jetzt:

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

Und das gleiche für std::wstring, was mehr als praktisch ist.


1
Das ist großartig und ich habe es in ein paar iPhone-Projekten verwendet. Eine Sache, die mir auffiel, war, dass ich, wenn ich Apples Unit-Test-Framework ausführte und eine Bibliothek testete, die diese Methoden verwendet, die Datei mit den String-Konvertierungsmethoden als eine der "Compile Sources" in die "Build Phases" für aufnehmen musste der Unit-Test. Seltsam.
David

1
Ja, der Unit-Test ist im Wesentlichen ein eigenes kleines Programm und muss Zugriff auf denselben Code haben. Auch ein
großes Lob

1
Wissen Sie, warum hier ( developer.apple.com/documentation/foundation/nsstring/… ) steht "Das zurückgegebene Objekt kann sich vom ursprünglichen Empfänger unterscheiden"? Was bedeutet das und wie würden wir wissen, ob es anders ist?
isJulian00

1
@izzyMachado Diese Art von Sprache in den Dokumenten bedeutet normalerweise, dass sie sich das "Recht" unter dem Schnittstellenvertrag vorbehalten, die Eingabezeichenfolge zu analysieren, zu bereinigen oder zu kanonisieren. Das heißt, es ist möglicherweise kein Roundtrip und dennoch ein Vergleich ==, sondern entweder die "engste" oder die "beste" Darstellung, die sie machen können. Der Empfänger ist in diesem Fall die NSStringKlassenimplementierung, und der zurückgegebene Wert ist kein Objective-C-Objekt, sodass sie dies möglicherweise auch mit einer Standardsprache abdecken.
Wert

Wissen Sie, warum dies immer noch funktioniert, wenn wir initWithUTF8String verwenden und die Zeichenfolge Nicht-utf8-Zeichen enthält. Wie kann die Zeichenfolge weiterhin verwendet werden (wenn es sich um Mint-UTF-8 handelt) und ausgedruckt werden, sobald es sich um einen NSString handelt?
isJulian00

21
NSString* mystring = [NSString stringWithUTF8String:stdstring.c_str()];

macht dies den NSString UTF8? oder welche Kodierung wäre der NSString?
isJulian00

14

Apple hat jetzt eine neue Möglichkeit, diese Konvertierung durchzuführen. In XCode7 habe ich die Option Bearbeiten> Konvertieren> In moderne Ziel-C-Syntax ... verwendet, um dies herauszufinden. Es wird ein Shorthand @ -Symbol verwendet.

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

3

Ich habe auch gefunden, dass:

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

Funktioniert wie ein Champion.


3
Das ist ziemlich unsicher und funktioniert garantiert nicht. standardString, wenn ein std :: string, ein C ++ - Objekt ist. C ++ - Objekte können nicht sicher an verschiedene Funktionen übergeben werden (verschiedene Vorlagen lösen dieses Problem in C ++ 11). Wenn es funktioniert, ist es ein Zufall und fast jeder Compiler warnt Sie zumindest davor (wenn es zunächst kein Fehler ist).
Vitali

3

Hier ist das Code-Snippet / Beispiel:

string str_simple = "HELLO WORLD";

//string to NSString
NSString *stringinObjC = [NSString stringWithCString:str_simple.c_str()
                                encoding:[NSString defaultCStringEncoding]];            
NSLog(stringinObjC);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.