Wie konvertiere ich einen NSString in einen std :: string?

94

Ich habe ein NSStringObjekt und möchte es in ein konvertieren std::string.

Wie mache ich das in Objective-C ++?

gabor
quelle
4
@rvalue kein Duplikat - nur die entgegengesetzte Konvertierung.
Eric

Antworten:

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

Bearbeiten: Lassen Sie mich nach einigen Jahren auf diese Antwort eingehen. Wie zu Recht darauf hingewiesen, werden Sie wahrscheinlich wollen die Verwendung cStringUsingEncoding:mit , NSASCIIStringEncodingwenn Sie mit am Ende gehen std::string. Sie können UTF-8 mit normal verwenden std::strings, aber denken Sie daran, dass diese mit Bytes und nicht mit Zeichen oder sogar Graphemen arbeiten. Schauen Sie sich diese Frage und ihre Antwort an , um einen guten Einstieg zu erhalten .

Beachten Sie außerdem, dass Sie eine Darstellung der Zeichenfolge mit verlustbehaftet codiertem ASCII verwenden können, wenn Sie eine Zeichenfolge haben, die nicht als ASCII dargestellt werden kann, diese aber dennoch in einer Zeichenfolge enthalten soll std::stringund keine Nicht-ASCII-Zeichen enthalten soll Inhalt, und dann werfen Sie das auf IhredataUsingEncoding:allowLossyConversion:NSDatastd::string

JustSid
quelle
13
Vorsicht bei der Codierung. Während UTF-8 im Allgemeinen eine gute Wahl ist, müssen Sie -cStringUsingEncoding:stattdessen API verwenden, wenn die API, mit der Sie arbeiten, beispielsweise reines ASCII oder die Systemcodepage erwartet . :)
Jonathan Grynspan
13
Dies ist ein Speicherverlust, wenn Sie ihn nicht löschen. Der zurückgegebene Zeiger ist kein Objekt mit Objective-C-Referenzzählung. Im Allgemeinen sollten Sie die Verwendung des Operators new für std :: string vermeiden.
SiimKallas
Dies sollte nicht die akzeptierte Antwort sein und definitiv nicht das erste, was bei dieser Konvertierung berücksichtigt werden muss.
JBL
@JBL Nach nur 4 Jahren und ein paar Wochen ging ich herum, um meine Antwort zu erweitern. Ich hoffe es ist jetzt akzeptabler.
JustSid
@ JustSid Ich hätte meine Meinung präzisieren sollen, aber das andere Problem ist die Verwendung eines Zeigers standardmäßig. Tatsächlich hat ein Mitarbeiter mit einem ObjC-Hintergrund ohne C ++ - Kenntnisse verwendet, der ohne Löschen zu einem Speicherverlust führte. Und allgemeiner; wilde news sind verpönt und ein std::shared_ptroder std::unique_ptrsollte bevorzugt werden.
JBL
50

Wie Ynau im Kommentar vorgeschlagen hat, ist es im Allgemeinen besser, alles auf dem Stapel zu belassen, anstatt Heap (mit newerstellt die Zeichenfolge auf dem Heap), daher (unter der Annahme einer UTF8-Codierung):

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

Wie auf philjordan.eu vermerkt, könnte es auch sein, dass der NSString ist nil. In einem solchen Fall sollte die Besetzung folgendermaßen erfolgen:

// HINWEIS: Wenn foo null ist, wird eine leere C ++ - Zeichenfolge erzeugt

// anstatt den NULL-Zeiger von UTF8String zu dereferenzieren.

Dies würde Sie zu einer solchen Konvertierung führen:

NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
Bruno Bieri
quelle
1
Das ist enorm nützlich. Die Sorge, fast alle zu sehen, übersieht es. Ihr werdet auf NIL abstürzen.
P i