从NSString中指定位置中的UTF8字符

时间:2011-02-24 03:23:26

标签: iphone objective-c macos nsstring

    NSString* str = @"1二3四5";
    NSLog(@"%c",[str characterAtIndex:0]); 
    NSLog(@"%c",[str characterAtIndex:1]);  

NSString - characterAtIndex在ASCII字符上运行良好,但是如何在索引为2时获得UTF8字符?

- 更新 -
 似乎unichar(16bits)不能代表所有UTF8编码字符串(8bites到32bites),所以有没有任何方法从NSString获取char?

3 个答案:

答案 0 :(得分:6)

不幸的是,戴夫的答案并没有真正做到你想要的。提供给rangeOfComposedCharacterSequenceAtIndex的索引是UTF-16代码单元的索引,1或2或者是UTF-16代码点。因此,如果字符串中的第一个代码点需要2个代码单元,则1不是第二个UTF-16代码点...(rangeOfComposedCharacterSequenceAtIndex返回包含代码单元的代码点的范围。给定索引,所以如果你的第一个char需要2个代码单元,那么传递0或1的索引会返回相同的范围)。

如果要查找字符的UTF-8序列,可以使用UTF8String,然后解析结果字节以查找第n个字符的字节序列。或者你也可以从索引0开始使用rangeOfComposedCharacterSequenceAtIndex并迭代直到你到达第n个字符,然后将1或2个UTF-16代码单元转换为UTF-8代码单元。

我希望我们都缺少一些内容,这是内置的......

可能有帮助的类别的开始(需要边界检查!):

@interface NSString (UTF)

- (NSRange) rangeOfUTFCodePoint:(NSUInteger)number;

@end

@implementation NSString (UTF)

- (NSRange) rangeOfUTFCodePoint:(NSUInteger)number
{
    NSUInteger codeUnit = 0;
    NSRange result;
    for(NSUInteger ix = 0; ix <= number; ix++)
    {
        result = [self rangeOfComposedCharacterSequenceAtIndex:codeUnit];
        codeUnit += result.length;
    }
    return result;
}

@end

但使用char *而不是NSString

,这类内容效率更高

答案 1 :(得分:4)

您将使用更详细的方法:

NSRange rangeOfSecondCharacter = [str rangeOfComposedCharacterSequenceAtIndex:1];
NSString *secondCharacter = [str substringWithRange:rangeOfSecondCharacter];

......当然,有适当的界限和范围检查。请注意,这会为您提供 NSString ,一个对象,而不是unichar或其他一些原始数据类型。

答案 2 :(得分:0)

你为什么不尝试使用类似的东西:

const char *yourWantedCharacter = [[yourSourceString substringWithRange:yourRange] UTF8String];

其中 yourSourceString 是您的NSString对象, yourRange 是一个NSRange对象,其中所需字符的索引作为位置参数,长度参数为“0”(零)。