我有一个isAlpha的查找表。
for (int i = 0; i <= UCHAR_MAX; ++i)
p.isalphaLUT[i] = isalpha(i);
其中isalphaLUT是一个char数组...问题是isalphaLUT [i],其中i是ASCII范围之外的字符,(当我试图获得等效的ASCII值时,它打印4294967168)。我尝试将127以上的所有ASCII范围设置为0,但这不起作用。有问题的角色是ö。
答案 0 :(得分:2)
测试一个字符是否为字母的正确方法是测试它是否属于一个字母类别:Lu,Ll,Lt,Lm或Lo。您可以使用IBM的ICU库来执行此操作,它是一个非常流行的用于处理Unicode的库。
http://icu-project.org/apiref/icu4c/uchar_8h.html
您也可以直接使用ICU的u_isalpha
功能,或u_charType
来确定角色的类别。请注意,术语“字母”优先于“alpha”,因为Unicode中有许多非字母“字母”(例如中文字符)。
但是,您必须先解码角色。如果您使用的是char
数组,那么您的编码可能是ASCII,LATIN-1,Windows 1252,UTF-8或其他任何编码。如果您直接访问char
,它可能是签名或未签名的,具体取决于您的平台,这就是为什么您会得到一个明显错误的数字,如4294967168 - 这就是当字节0x80被解释为已签名char
,然后转为unsigned int
。
对于这种任务,使用查找表是一个非常糟糕的选择,因为表必须非常大 - 大约700k。相反,我建议使用ICU或创建一个字符范围表并在表中执行二进制搜索。这可能非常有效。
我正在开发一种工具来精确创建这些类型的表。该工具目前尚未准备好生产,但如果您喜欢冒险,可以使用它,自述文件中有如何使用它的示例。
答案 1 :(得分:0)
在使用它来索引数组之前,只检查字符的值是否在你的范围内怎么样?将“所有ASCII范围”设置为255以上(这没有意义btw,我听到的所有ASCII定义都是单字节编码)会产生一个相当庞大的查找表。
此外,ö
确实是一个字母字符。你为什么不想像一个人一样处理它?</ p>
答案 2 :(得分:0)
假设您使用的是默认语言环境,则isalpha()函数将为字母A-Z和a-z返回true - 其他任何内容都将使其返回false。为了进一步追求这一点,你需要了解字符编码(就像ASCII实际上的意思)和语言环境。