在我的iOS 5.1应用程序中,我使用的第三方库使用wchar_t
作为字符串。这在内部工作正常,但我有时需要为这样的字符串创建NSString
。我可以使用以下API:
- (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding
但是我应该使用什么编码?由于iOS中的wchar_t
为32位,因此候选编码为:
NSUTF32StringEncoding
NSUTF32BigEndianStringEncoding
NSUTF32LittleEndianStringEncoding
我应该使用哪个字节顺序?我应该使用与long NSHostByteOrder()
的结果相对应的编码字节顺序吗?
顺便说一下,哪个字节顺序是NSUTF32StringEncoding
代表?是要检查字节并推断字节顺序?使用getBytes:maxLength:usedLength:encoding:options:range:remainingRange:
请注意,我并不关心平台之间的数据交换(尽管有一天我可能不得不面对这个问题)。
谷歌搜索并没有多大帮助。
我的预感是这是编译器定义的,例如我写的时候编译器(CLang)使用了什么编码:
wchar_t *s = L"string with non ascii unicode characters such as éèüçß";
当然,编写一个小的示例程序并找出答案很容易,但我想要一个不依赖于编译器特定实现的解决方案。
如果你相信我很困惑,那是因为我有点。
答案 0 :(得分:4)
这就是为什么wchar_t
无法推荐的原因,除非您需要直接使用Windows API。
在iOS上,wchar_t
是UTF-32,具有本机字节顺序。这技术上与NSUTF32StringEncoding
不同,它表示带有BOM的字节顺序。
这是我上次回答这个问题(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
,但不一定相反。它会在前面粘贴BOM(不合需要的),它甚至可能会以错误的结尾给你数据。
使用NSUTF32StringEncoding
也可能导致错误甚至从wchar_t
转移到NSString
,但这种情况极不可能。
答案 1 :(得分:0)
正如已经指出的那样,假设wchar_t *字符串是UTF-32编码是不安全的。
如果您非常关注此问题并希望它尽可能健壮,请使用wcstombs_l()将wchar_t *字符串转换为UTF-8编码的char *字符串。使用newlocale()指定“UTF-8”语言环境。这将可靠地将wchar_t *字符串转换为UTF-8编码的char *字符串。您可以使用mbstowcs_l()转换回来。
一旦你有一个UTF-8编码的char *,你就应该使用NSUTF8StringEncoding进行NSString转换。是的,这是一个额外的箍。跳过它。