Comment convertir une NSString en std :: string?

Réponses:

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

Edit: Après quelques années, permettez-moi de développer cette réponse. Comme indiqué à juste titre, vous voudrez probablement utiliser cStringUsingEncoding:avec NSASCIIStringEncodingsi vous allez finir par utiliser std::string. Vous pouvez utiliser UTF-8 avec normal std::strings, mais gardez à l'esprit que ceux-ci fonctionnent sur des octets et non sur des caractères ou même des graphèmes. Pour un bon "démarrage", consultez cette question et sa réponse .

Notez également que si vous avez une chaîne qui ne peut pas être représentée en ASCII mais que vous la voulez toujours dans un std::stringet que vous ne voulez pas de caractères non-ASCII, vous pouvez utiliser dataUsingEncoding:allowLossyConversion:pour obtenir une NSDatareprésentation de la chaîne avec ASCII encodé avec perte contenu, puis lancez-le à votrestd::string

JustSid
la source
13
Attention à l'encodage. Bien que l'UTF-8 soit généralement un bon choix, si l'API avec laquelle vous travaillez attend, par exemple, de l'ASCII pur ou la page de codes système, vous devrez l'utiliser à la -cStringUsingEncoding:place. :)
Jonathan Grynspan
13
Il s'agit d'une fuite de mémoire si vous ne le supprimez pas, le pointeur renvoyé n'est pas un objet compté de référence Objective-C. En général, vous devriez éviter d'utiliser l'opérateur new pour std :: string.
SiimKallas
Cela ne devrait pas être la réponse acceptée et certainement pas la première chose à considérer lors de cette conversion.
JBL
@JBL Après seulement 4 ans et quelques semaines, je suis allé élargir ma réponse. J'espère que c'est plus acceptable maintenant.
JustSid
@JustSid J'aurais dû préciser mon avis, mais l'autre problème est l'utilisation d'un pointeur par défaut. En fait, un collègue avec une formation ObjC, sans aucune connaissance C ++, a utilisé cela, sans supprimer, aboutissant à une fuite de mémoire. Et plus généralement; les wild newsont mal vus, et un std::shared_ptrou std::unique_ptrdevrait être préféré.
JBL
50

Comme Ynau l'a suggéré dans le commentaire, dans un cas général, il serait préférable de tout garder sur la pile au lieu du tas (en utilisant newcrée la chaîne sur le tas), donc (en supposant le codage UTF8):

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

Comme indiqué sur philjordan.eu, il se peut également que la NSString soit nil. Dans un tel cas, le casting doit être fait comme ceci:

// NOTE: si foo est nul, cela produira une chaîne C ++ vide

// au lieu de déréférencer le pointeur NULL de UTF8String.

Cela vous conduirait à une telle conversion:

NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
Bruno Bieri
la source
1
C'est extrêmement utile. S'inquiéter de voir presque tout le monde le néglige. Vous allez vous écraser sur NIL.
P i