2012-05-23 4 views
1

Im my iOS 5.1 приложение, я использую стороннюю библиотеку, которая использует строки wchar_t для строк. Это работает нормально внутри, но мне иногда нужно создать NSString для такой строки. Я могу использовать следующий API:Что такое утверждение iOS wchar_t?

- (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding 

Но какую кодировку я должен использовать? Поскольку wchar_t в прошивке составляет 32 бит, кандидата кодироаки:

NSUTF32StringEncoding 
NSUTF32BigEndianStringEncoding 
NSUTF32LittleEndianStringEncoding 

Какого порядка байт я должен использовать? Должен ли я использовать порядок байтов кодирования, соответствующий результату long NSHostByteOrder()?

И, кстати, какой порядок байтов NSUTF32StringEncoding представляет? Будет ли рассмотрено байты и вывести порядок байтов? И что это даст при конвертации от NSString с getBytes:maxLength:usedLength:encoding:options:range:remainingRange:?

Обратите внимание, что меня не интересует обмен данными между платформами здесь (хотя мне, возможно, придется столкнуться с этой проблемой слишком рано).

Гуглинг вокруг не помог.

Моя догадка заключается в том, что это определено в компиляторе, например. какая кодировка используется мой компилятор (лязг), когда я пишу:

wchar_t *s = L"string with non ascii unicode characters such as éèüçß"; 

Конечно, это достаточно просто написать небольшой пример программы и выяснить, но я хотел бы решение, которое не опирается на конкретной реализации моего компилятора.

Если вы считаете, что я в замешательстве, это потому, что я немного.

+0

Вы чрезмерно задумываетесь об этом. Библиотека будет скомпилирована, чтобы использовать конечность вашего компилятора C. NSUTF32StringEncoding должно быть хорошо для большинства вещей. Игра меняется, если вы экспортируете на не-iOS хосты. – starbolin

+0

В этом случае вам нужно добавить опцию для экспорта файлов. Формат файла экспорта должен быть большим, чтобы быть совместимым с сетевым байтом. – starbolin

+0

@starbolin: 'NSUTF32StringEncoding' проблематично, это особенно вызовет проблемы в направлении' NSString' -> 'wchar_t'. –

ответ

4

Вот почему wchar_t нельзя рекомендовать, за исключением случаев, когда вам нужно работать непосредственно с Windows API.

На iOS, wchar_t есть UTF-32 с собственным порядком байтов. Это технически не то же самое, что NSUTF32StringEncoding, что указывает либо порядок байтов с спецификацией.

Вот некоторые копии пасту из последнего времени я ответил на этот вопрос (link):

#include <machine/endian.h> 
#if BYTE_ORDER == BIG_ENDIAN 
#define WCHAR_ENCODING NSUTF32BigEndianStringEncoding 
#elif BYTE_ORDER == LITTLE_ENDIAN 
#define WCHAR_ENCODING NSUTF32LittleEndianStringEncoding 
#endif 

Проблема с использованием NSUTF32StringEncoding в том, что она будет работать только для преобразования wchar_t в NSString, но не обязательно другой способ вокруг. Он будет прикреплять спецификацию на передней панели (нежелательно), и он может даже дать вам данные в неправильном знаке.

Также возможно, что использование NSUTF32StringEncoding приведет к ошибкам даже от wchar_t до NSString, но это крайне маловероятно.

+0

Спасибо, это имеет смысл –

0

Как уже указывалось, небезопасно предположить, что строка wchar_t * кодируется в кодировке UTF-32.

Если вы очень обеспокоены этим и хотите, чтобы он был устойчивым насколько возможно, преобразуйте строку wchar_t * в кодированную строку UTF-8 char *, используя wcstombs_l(). Укажите локаль UTF-8 с помощью newlocale().Это надежно преобразует строку wchar_t * в кодированную строку символов UTF-8. Вы можете преобразовать обратно с помощью mbstowcs_l().

Как только у вас есть кодированный символ UTF-8 *, вы должны быть настроены для преобразований NSString с помощью NSUTF8StringEncoding. Да, это дополнительный обруч. Просто перепрыгните через него.

+0

Это не безопасно в целом. Однако это безопасно для iOS. –

+0

Кроме того, почему небезопасно считать, что строка wchar_t * кодируется в кодировке UTF-32, учитывая, что она равна 32 бит? Это из-за разницы в тонлах между UCS-4 и UTF-32? Или что-то мне не хватает? –

+0

Кроме того, если небезопасно «предполагать», как «wcstombs_l» сделает это без «принятия»? Будет ли он проверять текст, ищущий спецификацию или что-то еще? –

Смежные вопросы