Як перетворити NSString на std :: string?


Відповіді:


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


13
Обережне кодування. Хоча UTF-8, як правило, хороший вибір, якщо API, з яким ви працюєте, передбачає, скажімо, чистий ASCII або системну кодову сторінку, вам доведеться використовувати його -cStringUsingEncoding:. :)
Джонатан Грінспан

13
Це витік пам’яті, якщо його не видалити, повернутий покажчик не є об’єктом підрахунку посилань Objective-C. Як правило, слід уникати використання оператора new для std :: string.
SiimKallas

Це не повинна бути прийнятою відповіддю і, безумовно, не першим, що слід враховувати при здійсненні цього перетворення.
JBL

@JBL Лише через 4 роки та кілька тижнів я ходив, щоб розширити свою відповідь. Сподіваюсь, зараз це прийнятніше.
JustSid

@JustSid Я повинен був уточнити свою думку, але інша проблема полягає у використанні вказівника за замовчуванням. Насправді колега з фоном ObjC, який не знав мови C ++, використовував це, не видаляючи, і потрапити в витік пам'яті. І більш загально; дикі news насуплюються, і a std::shared_ptrабо std::unique_ptrслід віддати перевагу.
JBL

50

Як запропонував у коментарі Ynau, у загальному випадку було б краще тримати все в стеці, а не купу (використовуючи newстворює рядок у купі), отже (припускаючи кодування UTF8):

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

8

Як зазначено на philjordan.eu, також може бути, що NSString є nil. У такому випадку кастинг слід робити так:

// ПРИМІТКА: якщо foo дорівнює нулю, це дасть порожній рядок C ++

// замість відмінювання посилання на покажчик NULL від UTF8String.

Це призведе до такого перетворення:

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

1
Це надзвичайно корисно. Хвилюючись побачити, майже всі це не помічають. Y'all gona crash on NIL.
P i
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.