utf8 支持的字符比较全,相应的,它就必须是变长编码。它大致的原理如下:
UTF-8
编码范围 | 编码 | 编码表示的值 |
---|---|---|
U+000000-U+00007f | 0xxxxxxx | 0xxxxxxx |
U+000080-U+0007ff | 110yyyxx | 00000yyy xxxxxxxx |
U+000800-U+00ffff | 1110yyyy 10yyyyxx 10xxxxxx | yyyyyyyy xxxxxxxx |
U+010000-U+10ffff | 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx | 000zzzzz yyyyyyyy xxxxxxxx |
从上表可以看出,每来一个新的字节,utf8分3种情况:
(1)以0打头,那么之后7位就是内容,这是ASCII的字符
(2)以10打头,说明当前字节保存部分字符内容,之后6位是这个字符的内容
(3)以110/1110/11110/…打头,说明这是字符的起始位,并且有几个1,这个字符就有多少个字节。
以上表为例,就能明白了。
在看处理utf8编码的代码中会看到类似于下面的代码:
int strlen_utf8(char *s)
{
int i = 0, j = 0;
while (s[i])
{
if ((s[i] & 0xc0) != 0x80) j++; // 这就是在处理字符的连续内容
i++;
}
return j;
}