Comment convertir std :: string en NSString?

97

Salut, j'essaye de convertir un standard std::stringen un NSStringmais je n'ai pas beaucoup de chance.

Je peux convertir avec succès de un NSStringà un std::stringavec le code suivant

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

Cependant, j'obtiens une erreur de compilation lorsque j'essaye ce qui suit

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

L'erreur que j'obtiens est

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

Est-ce que j'ai râté quelque chose?

Merci d'avance.

Anthony McCormick
la source
4
Ce doit être une faute de frappe, mais il vous manque '@' pour la chaîne littérale dans 'NSString * realm = "Hollywood";' ligne.
Vladimir

Réponses:

111

Récupère la chaîne C de std :: string pour la conversion:

NSString *errorMessage = [NSString stringWithCString:REALM.c_str() 
                                   encoding:[NSString defaultCStringEncoding]];
Vladimir
la source
Cela ne semble pas être une bonne réponse, comme le dit la documentation: / * Codage dépendant de l'utilisateur dont la valeur est dérivée de la langue par défaut de l'utilisateur et potentiellement d'autres facteurs. L'utilisation de ce codage peut parfois être nécessaire lors de l'interprétation de documents utilisateur avec des codages inconnus, en l'absence d'autres indices. Ce codage doit être utilisé rarement, voire pas du tout. Notez que certaines valeurs potentielles ici peuvent entraîner des conversions de codage inattendues, même du contenu NSString assez simple - par exemple, des caractères de ponctuation avec un codage bidirectionnel. * /
cyrilchampier
31
[NSString stringWithUTF8String: mystring.c_str ()] semble plus approprié, car la std :: string provient plus probablement de votre propre code, qui est probablement en UTF8.
cyrilchampier
Savez-vous pourquoi ici ( developer.apple.com/documentation/foundation/nsstring/… ) il est dit "L'objet retourné peut être différent du récepteur d'origine"? Qu'est-ce que cela signifie et comment saurions-nous si c'est différent?
isJulian00
@cyrilchapier et si notre fichier .mm dit "aucun encodage spécifique spécifié"?
isJulian00
54

Tout d'abord, vous devez utiliser Objective-C ++ pour que cela fonctionne le moins du monde; moyen le plus simple de vous assurer que vous renommez tous vos *.mfichiers en*.mm

De loin, le moyen manuel le plus utilisable (non obsolète) pour obtenir un C ++ std::stringdans un NSStringest avec:

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

Cela fonctionnera dans la plupart des cas - et si vous ne faites pas de détection et de conversion d'encodage spécifiques, UTF-8 va vous donner un bon résultat pour avoir des caractères non latins "juste fonctionner".

Si vous créez une application plus volumineuse ou si vous n'êtes pas le seul à y travailler, vous voudrez probablement quelque chose de plus facile à appliquer.

Adapté des archives de la liste de diffusion 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

Avec cela en place (et correctement #importédité), vous pouvez maintenant:

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

Et la même chose pour std::wstring, ce qui est plus que pratique.

rvaleur
la source
1
C'est rad et je l'ai utilisé dans quelques projets iphone. Une chose que j'ai remarquée est que si j'exécutais le framework de test unitaire d'Apple et que je testais une bibliothèque qui utilise ces méthodes, je devais inclure le fichier contenant les méthodes de conversion de chaîne comme l'une des "Sources de compilation" dans les "Phases de construction" pour le test unitaire. Bizarre.
David
1
Oui, le test unitaire est essentiellement son propre petit programme et doit avoir accès au même code. Aussi, bravo pour avoir réellement écrit des tests ;-)
rvalue
1
Savez-vous pourquoi ici ( developer.apple.com/documentation/foundation/nsstring/… ) il est dit "L'objet retourné peut être différent du récepteur d'origine"? Qu'est-ce que cela signifie et comment saurions-nous si c'est différent?
isJulian00
1
@izzyMachado ce type de langage dans les documents signifie généralement qu'ils se réservent le «droit» dans le cadre du contrat d'interface d'analyser, de nettoyer ou de canoniser la chaîne d'entrée. c'est-à-dire qu'il pourrait ne pas aller-retour et toujours comparer, ==mais plutôt être la représentation «la plus proche» ou «meilleure» qu'ils peuvent faire. Le récepteur dans ce cas est l' NSStringimplémentation de la classe, et la valeur renvoyée n'est pas un objet Objective-C, donc ils pourraient également couvrir cela avec un langage standard.
rvalue le
Savez-vous pourquoi cela fonctionne toujours lorsque nous utilisons initWithUTF8String et que la chaîne comprend des caractères non utf8, comment est-il toujours capable d'utiliser la chaîne (si elle est mint UTF-8) et de l'imprimer une fois qu'elle devient une NSString?
isJulian00
21
NSString* mystring = [NSString stringWithUTF8String:stdstring.c_str()];
John Bowers
la source
cela fait-il le NSString UTF8? ou quel encodage serait la NSString?
isJulian00
14

Apple a maintenant une nouvelle façon dont ils veulent que vous effectuiez cette conversion. Dans XCode7, j'ai utilisé l'option Edition> Convertir> Vers la syntaxe moderne de l'objectif C ... pour le savoir. Il utilise un symbole @ abrégé.

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

J'ai également constaté que:

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

Fonctionne comme un champion.

BadPirate
la source
3
C'est assez dangereux et pas garanti de fonctionner. standardString si un std :: string, est un objet C ++. Les objets C ++ ne sont pas sûrs pour passer à des fonctions variadiques (les modèles variadiques résolvent ce problème en C ++ 11). Si cela fonctionne, c'est un hasard et presque tous les compilateurs vous avertiront à tout le moins de ne pas faire cela (si ce n'est pas une erreur pour commencer).
Vitali
3

Voici l'extrait de code / l'exemple:

string str_simple = "HELLO WORLD";

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