Как преобразовать NSString в std :: string?

94

У меня есть NSStringобъект, и я хочу преобразовать его в std::string.

Как мне это сделать в Objective-C ++?

Габор
источник
Обманывание stackoverflow.com/q/3552195/918764
rvalue
4
@rvalue не дубликат - как раз обратное преобразование.
eric

Ответы:

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

Изменить: через несколько лет позвольте мне расширить этот ответ. Как правильно указано, вы, скорее всего, захотите использовать cStringUsingEncoding:с, NSASCIIStringEncodingесли собираетесь использовать std::string. Вы можете использовать UTF-8 с обычным кодом std::strings, но имейте в виду, что они работают с байтами, а не с символами или даже графемами. Для хорошего начала ознакомьтесь с этим вопросом и ответом на него .

Также обратите внимание, что если у вас есть строка, которая не может быть представлена ​​как ASCII, но вы все еще хотите, чтобы она была в, std::stringи вы не хотите, чтобы там были символы, отличные от ASCII, вы можете использовать dataUsingEncoding:allowLossyConversion:для получения NSDataпредставления строки с кодировкой ASCII с потерями контент, а затем бросьте это в свойstd::string

JustSid
источник
13
Осторожно с кодированием. Хотя UTF-8 обычно является хорошим выбором, если API, с которым вы работаете, ожидает, скажем, чистого ASCII или системной кодовой страницы, вам придется использовать -cStringUsingEncoding:вместо этого. :)
Jonathan Grynspan 03
13
Это утечка памяти, если вы не удалите ее, возвращаемый указатель не является объектом с подсчетом ссылок Objective-C. В общем, вам следует избегать использования оператора new для std :: string.
SiimKallas
Это не должен быть общепринятым ответом и, безусловно, не первое, что нужно учитывать при преобразовании.
JBL
@JBL Всего через 4 года и несколько недель я решил расширить свой ответ. Надеюсь, теперь это более приемлемо.
JustSid,
@JustSid Я должен был уточнить свое мнение, но другая проблема - это использование указателя по умолчанию. Фактически, коллега с опытом работы с ObjC, без знания C ++, использовал, что, без удаления, привело к утечке памяти. И вообще; дикие newс неодобрением, и std::shared_ptrили std::unique_ptrдолжны быть предпочтительным.
JBL
50

Как предложил Ynau в комментарии, в общем случае было бы лучше сохранить все в стеке, а не в куче (использование newсоздает строку в куче), следовательно (при условии кодировки UTF8):

NSString *foo = @"Foo";
std::string bar([foo UTF8String]);
Marco83
источник
8

Как указано на philjordan.eu, возможно, что NSString - это nil. В таком случае слепок следует производить так:

// ПРИМЕЧАНИЕ: если foo равно nil, будет создана пустая строка C ++

// вместо разыменования NULL-указателя из UTF8String.

Это привело бы вас к такому преобразованию:

NSString *foo = @"Foo";
std::string bar = std::string([foo UTF8String], [foo lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
Бруно Бьери
источник
1
Это очень полезно. Беспокоясь о том, чтобы увидеть, почти все не замечают этого. Y'all gona сбой на NIL.
Пи