呼吸de艺术

Live in your world, get owned in mine

Read UTF8 Code at Specify Position From an NSString

| Comments

如何获取nsstring制定某个位置的utf8编码的字符呢?

我也不知道,所以在stackoverflow问了下.

很快就有人回复了解决方案.

在贴代码之前写介绍下几个编码格式:

UTF8 和 UTF16均为字符编码方式.
UTF-8使用一至四個位元組為每個字符編碼:

  1. 128個US-ASCII字符只需一個位元組編碼(Unicode範圍由U+0000至U+007F)。
  2. 帶有附加符号拉丁文希臘文西里爾字母亞美尼亞語希伯來文阿拉伯文敘利亞文它拿字母則需要二個位元組編碼(Unicode範圍由U+0080至U+07FF)。
  3. 其他基本多文種平面(BMP)中的字元(這包含了大部分常用字)使用三個位元組編碼。
  4. 其他極少使用的Unicode 輔助平面的字元使用四位元組編碼。

UTF-16Unicode的其中一個使用方式。UTF是Unicode/UCS Transformation Format,即把Unicode轉做某種格式的意思。

其編碼方法是:

  1. 如果字符編碼U小於0x10000,也就是十進制的0到65535之內,則直接使用兩字節表示;
  2. 如果字符編碼U大於0x10000,由於UNICODE編碼範圍最大為0x10FFFF,從0x10000到0x10FFFF之間 共有0xFFFFF個編碼,也就是需要20個bit就可以標示這些編碼。用U’表示從0-0xFFFFF之間的值,將其前 10 bit作為高位和16 bit的數值0xD800進行 邏輯or 操作,將後10 bit作為低位和0xDC00做 邏輯or 操作,這樣組成的 4個byte就構成了U的編碼。

而NSString使用的就是unicode存储的, 唯一一个获取unichar的方法叫做 -characterAtIndex: , 但是问题是 unichar 其实是个 unsigned short,也就是2个字节,所以它并不能展现所有的字符.

终极解决方法:

NSString_Read_UTF8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@interface NSString (UTF8)

- (NSRange) rangeOfUTFCodePoint:(NSUInteger)number;

@end

@implementation NSString (UTF8)

- (NSRange) rangeOfUTFCodePoint:(NSUInteger)number
{
    if (number >= [self length]) {
        return NSMakeRange(NSNotFound, NSNotFound);
    }

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

@end

Comments