在过去的几天里,我一直在阅读关于Unicode和UTF-8的文章,我经常遇到类似于下面这样的逐位比较:
int strlen_utf8(char *s)
{
int i = 0, j = 0;
while (s[i])
{
if ((s[i] & 0xc0) != 0x80) j++;
i++;
}
return j;
}
谁能澄清一下与0xc0的比较,并检查它是否是最重要的位?
谢谢!
编辑: ANDed,而不是比较,使用了错误的单词;)
发布于 2010-10-12 11:51:45
这不是与0xc0
的比较,而是与0xc0
的逻辑AND运算。
位掩码0xc0
是11 00 00 00
,所以和所做的是只提取最高的两位:
ab cd ef gh
AND 11 00 00 00
-- -- -- --
= ab 00 00 00
然后将其与0x80
(二进制10 00 00 00
)进行比较。换句话说,if
语句检查该值的前两位是否不等于10
。
“为什么?”我听到你问。嗯,这是个好问题。答案是,在UTF-8中,所有以位模式10
开头的字节都是多字节序列的后续字节:
UTF-8
Range Encoding Binary value
----------------- -------- --------------------------
U+000000-U+00007f 0xxxxxxx 0xxxxxxx
U+000080-U+0007ff 110yyyxx 00000yyy xxxxxxxx
10xxxxxx
U+000800-U+00ffff 1110yyyy yyyyyyyy xxxxxxxx
10yyyyxx
10xxxxxx
U+010000-U+10ffff 11110zzz 000zzzzz yyyyyyyy xxxxxxxx
10zzyyyy
10yyyyxx
10xxxxxx
所以,这个小代码段所做的就是遍历UTF-8字符串的每个字节,并对不是连续字节的所有字节进行计数(即,它将获得字符串的长度,如广告所示)。有关更多详细信息,请参阅this wikipedia link,有关入门知识,请参阅Joel Spolsky's excellent article。
顺便说一下,这是一个有趣的问题。您可以按如下方式对UTF-8流中的字节进行分类:
高位设置为0
的
10
的1
位的数量表示此序列总共有多少个字节(110...
表示两个字节,1110...
表示三个字节等)。https://stackoverflow.com/questions/3911536
复制相似问题