1

我现在正在使用一个处理 unicode 字符的 iOS 应用程序,但是将 unicode 十六进制值(以及 int 值)转换为字符似乎存在一些问题。

例如,我想获取 Unicode 值为 c491 的字符“đ”,但在此代码之后:

NSString *str = [NSString stringWithUTF8String:"\uc491"];

str 的值不是“đ”而是“쓉”(韩语单词)。

我也用过:

int c = 50321; // 50321 is int value of 'đ'
NSString *str = [NSString stringWithCharacters: (unichar *)&c length:1];

但是上面两段代码的结果是一样的。

我不明白这里有什么问题,请帮助!

4

1 回答 1

3

简短的回答

要指定đ,可以通过以下方式指定(未经测试):

@"đ"
@"\u0111"
@"\U00000111"
[NSString stringWithUTF8String: "\u0111"]
[NSString stringWithUTF8String: "\xc4\x91"]

请注意,最后 2 行使用 C 字符串文字而不是 Objective-C 字符串对象文字结构@"..."

作为一个简短的解释,\u0111是 Unicode 转义序列đ,其中U+0111是字符的代码点đ

最后一个示例显示了如何在 C 字符串文字中指定đ(which is c4 91) 的 UTF-8 编码,然后将 UTF-8 编码中的字节转换为正确的字符。

上面的例子改编自这个答案这个博客文章。该博客还涵盖了Unicode 中基本多语言平面(平面 0)之外的字符的棘手情况。

Unicode 转义序列(C99 中的通用字符名称)

根据此博客1

在 C99 的 TC2 修正案中,Unicode 转义序列被添加到 C 语言中,并在 Mac OS X 10.5 中被添加到 Objective-C 语言(用于 NSString 文字)中。

C99 TC2 草案的第 65 页显示\unnnnor \Unnnnnnnnwhere nnnnor nnnnnnnnare "short-identifier as defined by ISO/IEC 10646 standard",大致意思是hexadecimal code point。注意:

通用字符名称不得指定短标识符小于 00A0 的字符,除了 0024 ( $)、0040 ( @) 或 0060 ( `),也不应指定 D800 到 DFFF 范围内的字符。

字符集与字符编码

您似乎对代码点U+0111和 UTF-8 编码c4 91(将字符表示为字节)感到困惑。UTF-8 编码是 Unicode 字符集的编码之一,码位是分配给字符集中字符的数字。这篇维基百科文章非常清楚地解释了含义上的差异。

编码字符集(CCS) 指定如何使用称为代码点的多个(通常为非负)整数值来表示字符集。[...]

字符编码形式(CEF) 指定将编码字符集的整数代码转换为一组大小有限的整数代码值,这些值有助于在系统中存储,该系统使用固定数量的比特以二进制形式表示数字 [...]

还有其他编码,例如 UTF-16 和 UTF-32,它们可能会给出磁盘上字符的不同字节表示,但由于 UTF-8、UTF-16 和 UTF-32 都是针对 Unicode 字符集的编码,因此代码相同字符的点在所有 3 种编码之间都是相同的。

脚注

1:我认为博客是正确的,但如果有人能找到苹果关于这一点的官方文档,那就更好了。

于 2013-02-28T09:29:24.523 回答