2010-08-23 5 views
77

Salut, je suis en train de convertir un std::string standard en NSString mais je n'ai pas beaucoup de chance.Comment convertir std :: string en NSString?

je peux convertir avec succès à partir d'un NSString à un std::string avec le code suivant

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

Cependant, je reçois une erreur de compilation lorsque je effectuez les opérations suivantes

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

L'erreur que je reçois est

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

Est-ce qu'il me manque quelque chose ici?

Merci d'avance.

+4

Il doit être une faute de frappe, mais vous manquez '@' pour chaîne littérale dans 'NSString * realm = "Hollywood";' ligne. – Vladimir

+0

Fixé dans mon édition. –

Répondre

88

Get c-string de std :: string pour la conversion:

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

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 indications. Cet encodage devrait être utilisé rarement, voire pas du tout. Notez que certaines valeurs potentielles peuvent entraîner des conversions de codage inattendues de contenu NSString assez simple, par exemple des caractères de ponctuation avec un codage bidirectionnel. */ – cyrilchampier

+23

[NSString stringWithUTF8String: mystring.c_str()] semble plus approprié, car la chaîne std :: provient probablement de votre propre code, ce qui est probablement le cas dans UTF8. – cyrilchampier

42

Tout d'abord, vous avez à l'aide d'Objective-C++ pour que cela fonctionne dans le moindre; meilleure façon de faire en sorte que la renommer tous vos fichiers à *.mm*.m

De loin la façon la plus utile manuelle (non dépréciée) d'obtenir un std::string C++ dans un NSString est avec:

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

Cela fonctionne Dans la plupart des cas - et si vous ne faites pas de détection et de conversion d'encodage spécifique, UTF-8 va vous donner un bon résultat pour que les caractères non latins fonctionnent.

Si vous créez une application plus grande, ou si vous n'êtes pas la seule à y travailler, vous voudrez probablement avoir une application plus simple.

Adapté de cocoa-dev mailing list archives

@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 

Cela en place (et de façon appropriée #import ed), vous pouvez maintenant:

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

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

+1

Ceci est rad et je l'ai utilisé dans un couple de projets iphone. Une chose que j'ai remarquée était que si j'exécutais le cadre de test unitaire d'Apple et que je testais une bibliothèque utilisant 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". 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. En outre, félicitations pour écrire réellement des tests ;-) – rvalue

3

J'ai aussi trouvé que:

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

fonctionne comme un champion.

+3

C'est assez dangereux et pas garanti de travailler. standardString si une chaîne std :: string est un objet C++. Les objets C++ ne sont pas sûrs pour passer aux fonctions variadiques (les templates variadiques résolvent ce problème en C++ 11). Si cela fonctionne c'est un coup de chance et presque tous les compilateurs vous avertiront au moins de ne pas le faire (si ce n'est pas une erreur pour commencer). – Vitali

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

Apple a maintenant une nouvelle façon de faire cette conversion. En XCode7, j'ai utilisé l'option Editer> Convertir> Vers l'Objective C Syntaxe ... pour le trouver. Il utilise un symbole de raccourci @.

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

Voici l'extrait/exemple de code:

string str_simple = "HELLO WORLD"; 

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