У меня есть функция Win32, которую мне нужно портировать на iOS:
// Loads UTF-8 file and converts to a UTF-16 string
bool LoadUTF8File(char const *filename, wstring &str)
{
size_t size;
bool rc = false;
void *bytes = LoadFile(filename, &size);
if(bytes != 0)
{
int len = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)bytes, size, 0, 0);
if(len > 0)
{
str.resize(len + 1);
MultiByteToWideChar(CP_UTF8, 0, (LPCCH)bytes, size, &str[0], len);
str[len] = '\0';
rc = true;
}
delete[] bytes;
}
return rc;
}
// LoadFile returns the loaded file as a block of memory
// There is a 3 byte BOM which MultiByteToWideChar seems to ignore
// The text in the file is encoded as UTF-8
Я использую C ++ для этого, а не Objective C, и я пытался использовать mbstowcs и _mbstowcs_l. Кажется, они не ведут себя так же, как MultiByteToWideChar. Например, акцентированный символ в конце слова attaché неправильно конвертируется (версия Win32 корректно конвертирует его). Есть ли в стандартных библиотеках функция от UTF-8 до UTF-16?
Есть ли в версии Win32 ошибка, которую я не замечаю?
Длина, возвращаемая из MultiByteToWideChar, меньше, чем длина, возвращаемая из mbstowcs.
Странно, в этом маленьком тестовом случае
char *p = "attaché";
wstring str;
size_t size = strlen(p);
setlocale(LC_ALL, "");
int len = mbstowcs(null, p, size);
if(len > 0)
{
str.resize(len + 1);
mbstowcs(&str[0], p, size);
str[len] = '\0';
}
TRACE(L"%s\n", str.c_str());
len = MultiByteToWideChar(CP_UTF8, 0, p, size, null, 0);
if(len > 0)
{
str.resize(len + 1);
MultiByteToWideChar(CP_UTF8, 0, p, size, &str[0], len);
str[len] = '\0';
}
TRACE(L"%s\n", str.c_str());
Я получаю правильный вывод из mbcstowcs, и MultiByteToWideChar ошибочно преобразует последний символ в 65533 (REPLACEMENT_CHARACTER). Теперь я в замешательстве …
Вы застряли с использованием C ++ для этого или это просто так, как вы выбрали до сих пор, но открыты для этого и в Objective-C?
В Objective-C вы можете использовать [yourUTF8String dataUsingEncoding:NSUTF16StringEncoding]
чтобы получить NSData, содержащий байты UTF-16 представления строки.
Дополнительная гипотеза: обратите внимание, что ваш символ «é», который неправильно конвертируется в вашем примере, также может быть объяснен тем фактом, что ваше решение может не принимать форму NFD (или форму NFC, либо одну). Это означает, что если символ «é» закодирован в NFD как для «символа« e »с острым акцентом», он может интерпретироваться неправильно, тогда как форма NFC (как в «акцентированном символе e», то есть до составленный персонаж) Или наоборот.
Это всего лишь одна гипотеза, на самом деле это зависит от того, какой результат вы получите вместо ожидаемого символа «é», но это стоит проверить.
Других решений пока нет …