2010-08-23 17 views
77

Hola, estoy tratando de convertir un estándar std::string en un NSString pero no estoy teniendo mucha suerte.Cómo convertir std :: string a NSString?

puedo convertir con éxito de un NSString a un std::string con el siguiente código

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

Sin embargo, me sale un error de tiempo de compilación cuando intento el siguiente

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

El error que consigo es

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

¿Falta algo aquí?

Gracias de antemano.

+4

Tiene que ser un error tipográfico, pero que se está perdiendo '@' para la cadena literal en 'NSString * realm = "Hollywood";' línea. – Vladimir

+0

Solucionado en mi edición. –

Respuesta

88

obtener la letra C-secuencia de std :: string para la conversión:

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

Esto no parece ser una buena respuesta, ya que la documentación dice: /* La codificación dependiente del usuario que valora se deriva del lenguaje predeterminado del usuario y potencialmente de otros factores. El uso de esta codificación a veces puede ser necesario al interpretar documentos de usuario con codificaciones desconocidas, a falta de otros consejos. Esta codificación debe usarse raramente, si es que lo hace. Tenga en cuenta que algunos valores potenciales aquí pueden dar como resultado conversiones de codificación inesperadas incluso de contenido NSString bastante directo, por ejemplo, caracteres de puntuación con una codificación bidireccional. */ – cyrilchampier

+23

[NSString stringWithUTF8String: mystring.c_str()] parece más apropiado, ya que es más probable que std :: string provenga de su propio código, que probablemente esté en UTF8. – cyrilchampier

42

En primer lugar, tienes que estar usando Objective-C++ para que esto funcione en lo más mínimo; forma más fácil de asegurarse de que se cambie el nombre de todos sus *.m archivos a *.mm

Con mucho, el más fácil de usar de forma manual (no se use) de conseguir un C++ std::string en un NSString es con:

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

Esto funcionará en la mayoría de los casos, y si no está haciendo una detección y conversión de codificación específica, UTF-8 le dará un buen resultado al hacer que los caracteres no latinos funcionen.

Si está haciendo una aplicación más grande, o no es la única que trabaja en ella, sin embargo, probablemente querrá algo más fácil de aplicar.

Adaptado 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 

Con esto en contexto (y apropiadamente #import ed) que ahora puede:

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

Y lo mismo para std::wstring, que es más práctico.

+1

Esto es radical y lo he usado en un par de proyectos de iphone. Una cosa que noté fue que si estaba ejecutando el marco de pruebas unitarias de Apple y estaba probando una biblioteca que utiliza estos métodos, tenía que incluir el archivo que contenía los métodos de conversión de cadenas como una de las "Fuentes de compilación" en las "Fases de compilación" para la prueba unitaria Extraño. – David

+1

Sí, la prueba de la unidad es esencialmente su propio pequeño programa y necesita tener acceso al mismo código. Además, felicidades por escribir pruebas ;-) – rvalue

3

También he encontrado que:

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

funciona como un campeón.

+3

Eso es bastante inseguro y no se garantiza que funcione. standardString si std :: string, es un objeto C++. Los objetos C++ no son seguros para pasar a funciones variadas (las plantillas variadas resuelven este problema en C++ 11). Si funciona es una casualidad y casi todos los compiladores al menos te advierten que no hagas esto (si no es un error para empezar). – Vitali

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

Apple ahora tiene una nueva forma en que quieren que hagas esta conversión. En XCode7, utilicé la opción Editar> Convertir> A la sintaxis C del objetivo moderno para descubrir esto. Utiliza un símbolo de taquigrafía @.

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

Aquí es el fragmento de código/ejemplo:

string str_simple = "HELLO WORLD"; 

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