如何处理NSString中的32位unicode字符

时间:2013-12-12 07:42:04

标签: objective-c unicode nsstring

我有一个包含比U + FFFF更大的unicode字符的NSString,比如MUSICAL SYMBOL G CLEF符号''。我可以创建NSString并显示它。

NSString *s = @"A\U0001d11eB";  // "AB"
NSLog(@"String = \"%@\"", s);

日志正确并显示3个字符。这告诉我NSString做得很好,没有编码问题。

    String = "AB"

但是当我尝试使用方法

遍历所有字符时
- (unichar)characterAtIndex:(NSUInteger)index
一切都出错了。

类型 unichar 是16位,所以我希望音乐符号的字符错误。但是字符串的长度也不正确!

NSLog(@"Length = %d", [s length]);
for (int i=0; i<[s length]; i++)
{
    NSLog(@"  Character %d = %c", i, [s characterAtIndex:i]);
}

显示器

    Length = 4
      Character 0 = A
      Character 1 = 4
      Character 2 = .
      Character 3 = B

我应该使用哪些方法来正确解析我的NSString并获取我的3个unicode字符? 理想情况下,正确的方法应该返回类似 wchar_t 的类型来代替 unichar

谢谢

1 个答案:

答案 0 :(得分:5)

NSString *s = @"A\U0001d11eB";
NSData *data = [s dataUsingEncoding:NSUTF32LittleEndianStringEncoding];
const wchar_t *wcs = [data bytes];
for (int i = 0; i < [data length]/4; i++) {
    NSLog(@"%#010x", wcs[i]);
}

输出:

0x00000041
0x0001d11e
0x00000042

(该代码假定wchar_t的大小为4字节且是小端编码。)

lengthcharAtIndex:未提供预期结果,因为\U0001d11e 内部存储为UTF-16“代理对”。

一般Unicode字符串的另一种有用方法是

[s enumerateSubstringsInRange:NSMakeRange(0, [s length])
              options:NSStringEnumerationByComposedCharacterSequences
           usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    NSLog(@"%@", substring);
}];

输出:

A

B