iOS wchar_t的字节序是什么?

时间:2012-05-23 22:07:23

标签: ios string cocoa unicode character-encoding

在我的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:

从 NSString转换时会产生什么结果?

请注意,我并不关心平台之间的数据交换(尽管有一天我可能不得不面对这个问题)。

谷歌搜索并没有多大帮助。

我的预感是这是编译器定义的,例如我写的时候编译器(CLang)使用了什么编码:

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

当然,编写一个小的示例程序并找出答案很容易,但我想要一个不依赖于编译器特定实现的解决方案。

如果你相信我很困惑,那是因为我有点。

2 个答案:

答案 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转换。是的,这是一个额外的箍。跳过它。