2011-05-02 113 views
0

我有一个isAlpha查找表。处理ASCII范围外的字符

for (int i = 0; i <= UCHAR_MAX; ++i) 
p.isalphaLUT[i] = isalpha(i); 

其中isalphaLUT是字符数组...问题是isalphaLUT [I],其中i是ASCII范围之外的字符,(它打印4294967168当我尝试获得等效ASCII值)。我尝试设置127以上的所有ASCII码范围等于0,但这是行不通的。这个角色是这个ö。

+3

ASCII范围是[0,127],而不是[0,255]。 – jamesdlin 2011-05-02 08:41:15

+0

我关心ASCII [0,255]。此刻ö应该在0到255的ASCII范围内。但是,当我尝试打印等价值时,我得到了一些无意义的数字,并且isalphaLUT [i]在我应该返回false时返回true – Jake 2011-05-02 08:43:05

+1

ASCII是0..127,而不是0..255,jamesdlin是对的。 – 2011-05-02 09:00:08

回答

2

测试某个字符是否为字母的正确方法是测试它是否属于字母类别之一:Lu,Ll,Lt,Lm或Lo。您可以使用IBM的ICU库来执行此操作,它是一个非常受欢迎的用于处理Unicode的库。

http://icu-project.org/apiref/icu4c/uchar_8h.html

您也可以直接使用u_isalpha功能从ICU,或u_charType,以确定字符的类别。请注意,术语“字母”比“alpha”更受欢迎,因为Unicode中有许多非字母“字母”(如中文字符)。

但是,您必须先解码字符。如果您使用的是数组char,那么您的编码可能是ASCII,LATIN-1,Windows 1252,UTF-8或任何其他编码。如果直接访问char,则可能会根据您的平台进行签名或未签名,这就是为什么你会得到明显错误的数字,如4294967168 - 这正是当字节0x80被解释为有符号char时发生的情况,然后投到unsigned int

使用查找表对于这类任务来说是一个非常糟糕的选择,因为表必须非常大 - 约700k。相反,我建议使用ICU或创建一个字符范围表并在表中执行二进制搜索。这可能非常有效。

我正在创建一个工具来创建这些类型的表。该工具目前尚未准备好进行生产,但如果您喜欢冒险,则可以使用该工具,而自述文件中提供了有关如何使用该工具的示例。

https://github.com/depp/uniset

0

如何在使用索引数组之前检查字符的值是否在范围内?设置255以上的“所有ASCII范围”(这是没有意义的btw,所有我听说的ASCII的定义都是单字节编码)会导致一个相当巨大的查找表。

此外,ö确实是一个字母字符。你为什么不想像一个一样处理它?

0

假设您使用默认语言环境,则对于字母A-Z和a-z,isalpha()函数将返回true,否则其他任何操作都会使其返回false。为了进一步追求这一点,您需要了解字符编码(如ASCII实际意味着什么)和语言环境。