2011-10-09 83 views
1
/* utf-8: 0xc0, 0xe0, 0xf0, 0xf8, 0xfc */ 
static unsigned char _mblen_table_utf8[] = 
{ 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 
}; 

我敢打赌,它有什么做的编码,有没有人知道下面的代码可能做什么?

但究竟它是如何工作?

UPDATE

 while (str < ptr) 
     { 
      j = mblen[(*str)]; 
      tree_nput(r->tree, cr, sizeof(struct rule_item), str, j); 
      str += j; 
     } 
    } 
+0

我在什么情况下?这只是数组的声明。它没有做太多的事情。 – DeCaf

+0

你也应该找到并上传使用_mblen_table_utf8 – stacker

+0

这是代码相当hackish的和不正确** ** UTF-8多字节字符长度的表,而是作为输入数据已知是良好的形成,应该只要工作。 (至于什么是错的,表中的C0和C1字节被错误地编码为2字节字符起始字节,而且5字节和6字节字符错误,UTF-8对于字符最多4字节)。 –

回答

4

因为在一个多字节字符串的字符具有可变的长度,该表将每个字符的长度。

最后64个字符比一个字节宽,长度为26

的用法是类似的东西:

unsigned char current_char = *mbstr; 

for (i = 0; i < _mblen_table_utf8[current_char]; i++) { 
    /* treat *mbstr++ as a part of the current character */ 
} 
0

没有任何进一步的细节,上面的代码不正是这样:它声明静态无符号字符数组,并用花括号内的值进行初始化。

+0

准确地说,这段代码*定义了一个数组,而不仅仅是声明它。一个纯粹的*声明*不涉及初始化:http://publications.gbdirect.co.uk/c_book/chapter2/variable_declaration.html –

+0

正如...声明并初始化它。没有声明就不能有定义... –

2

历史上,每个字符都编码在7位(然后是8位),这足以编码欧洲语言字母。

只有128个第一个字符是每个人都通用的,其余的128个是通过代码页标准化的(ISO-8859-1就是一个例子)。

需要编码较长的字母语言,如中文导致Unicode effort每个字符都编码在几个字节上。

UTF-8是一种以高效,可变的代码长度方式编码Unicode字符的方法。这意味着您读取的第一个字节决定了字符字节序列的长度。

基本上,您的表是一个查找表,用于检查从用作表索引的字节开始的字节数。您将看到此表here的另一个版本,并附有说明。

我添加了表索引作为注释来更清楚:

/* utf-8: 0xc0, 0xe0, 0xf0, 0xf8, 0xfc */ 
static unsigned char _mblen_table_utf8[] = 
{ 
/*0x00*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x10*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x20*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x30*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x40*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x50*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x60*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x70*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x80*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0x90*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0xA0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0xB0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
/*0xC0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
/*0xD0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
/*0xE0*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
/*0xF0*/ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 
}; 
+0

您能否详细说明'其余128个通过代码页标准化'? –

+0

@new_perl当然。 128个最小字节被标准化为ASCII。 128个高位字节是OS /语言相关的。字符值与其字形之间的转换取决于我们所使用的代码页。即在代码页ISO-8859-1中未定义字符0x80,并且在代码页Windows-1252中等于“€”。简而言之:代码页是符合语言和操作系统的字形查找表。有关更多详细信息,请参见[常用字符编码](http://en.wikipedia.org/wiki/Character_encoding#Common_character_encodings)。 –

+0

代码点(我在别处听到的术语)和字符值是一样的东西,是不是? –

1

阵列似乎是一个查找表用于确定在UTF-8字符的字节数,给定的第一个字节。基本上,第一个字节(作为无符号值)用作数组中的索引,并且该索引处的元素给出UTF-8字符的字节序列的长度。

无效和中间序列字节似乎映射到此表中的1个字节,因此如果遇到不合适的位置,使用此表的代码可能会将它们视为单个字符(除非它特别忽略它们)。对于像这样的表

的一个用途是用于在UTF-8字符串计数字符(不字节,但Unicode字符)。每次你计算一个字符时,你会查看字符的长度,然后向前移动字符的字节序列的长度,而不是向前移动一个字节......只要你从字符的开始处开始并且字符串是一直有效的UTF-8。

相关问题