¿Cómo convierto un NSString en un std :: string?

Respuestas:

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

Editar: Después de unos años, permítanme ampliar esta respuesta. Como se señaló con razón, lo más probable es que desee usar cStringUsingEncoding:con NSASCIIStringEncodingsi va a terminar usando std::string. Puede usar UTF-8 con normal std::strings, pero tenga en cuenta que operan en bytes y no en caracteres o incluso grafemas. Para un buen "comienzo", consulte esta pregunta y su respuesta .

También tenga en cuenta que si tiene una cadena que no se puede representar como ASCII pero aún la quiere en un std::stringy no desea caracteres que no sean ASCII allí, puede usarla dataUsingEncoding:allowLossyConversion:para obtener una NSDatarepresentación de la cadena con ASCII codificado con pérdida contenido, y luego tírelo a tustd::string

JustSid
fuente
13
Cuidado con la codificación. Si bien UTF-8 es generalmente una buena opción, si la API con la que está trabajando espera, digamos, ASCII puro o la página de códigos del sistema, tendrá que usarla -cStringUsingEncoding:en su lugar. :)
Jonathan Grynspan
13
Esta es una pérdida de memoria si no la borra, el puntero devuelto no es un objeto contado de referencia de Objective-C. En general, debe evitar usar el operador new para std :: string.
SiimKallas
Esta no debería ser la respuesta aceptada y definitivamente no es lo primero a considerar al hacer esa conversión.
JBL
@JBL Después de solo 4 años y unas pocas semanas, di la vuelta para expandir mi respuesta. Espero que ahora sea más aceptable.
JustSid
@JustSid Debería haber precisado mi opinión, pero el otro problema es el uso de un puntero por defecto. De hecho, un compañero de trabajo con experiencia en ObjC, sin conocimientos de C ++, usó eso, sin borrar, terminando en una pérdida de memoria. Y más en general; salvajes news están bien vistas, y una std::shared_ptro std::unique_ptrdeben ser preferidos.
JBL
50

Como sugirió Ynau en el comentario, en un caso general sería mejor mantener todo en la pila en lugar de en el montón (el uso newcrea la cadena en el montón), por lo tanto (asumiendo la codificación UTF8):

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

Como se señaló en philjordan.eu , también podría ser que NSString sea nil. En tal caso, el yeso debe hacerse así:

// NOTA: si foo es nil, esto producirá una cadena C ++ vacía

// en lugar de eliminar la referencia al puntero NULL de UTF8String.

Esto lo llevaría a tal conversión:

NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
Bruno Bieri
fuente
1
Esto es tremendamente útil. Preocuparse por ver que casi todo el mundo lo está pasando por alto. Todos van a chocar con NIL.
P i