我有一个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获得正确的输出,而MultiBystToWideChar错误地将最后一个字符转换为65533(REPLACEMENT_CHARACTER)。现在我很困惑......
答案 0 :(得分:0)
您是否仍然坚持使用C ++,或者它只是您目前所选择的方式,但也可以在Objective-C中使用它吗?
在Objective-C中,您可以使用[yourUTF8String dataUsingEncoding:NSUTF16StringEncoding]
来获取包含字符串的UTF-16表示字节的NSData。
附加假设:请注意,在您的示例中未正确转换的“é”字符也可能是因为您的解决方案可能不采用NFD形式(或NFC形式,任一个)。这意味着如果“é”字符在NFD中编码为“具有急性重音的字符'e”,则可能无法正确解释而NFC形式(如“重音e字符”,即前直接组成的字符)它会。反之亦然。
这只是一个假设,实际上它取决于你的结果而不是你期望的“é”字符,但是值得检查。