【问题标题】:isalpha() giving an assertionisalpha() 给出一个断言
【发布时间】:2011-10-05 08:07:23
【问题描述】:

我有一个 C 代码,其中我在 ctype.h 中使用标准库函数 isalpha(),这是在 Visual Studio 2010-Windows 上。 在下面的代码中,如果 char c 是 '£',isalpha 调用会返回一个断言,如下面的快照所示:

char c='£';

if(isalpha(c))
{
    printf ("character %c is alphabetic\n",c);

}
else
{
    printf ("character %c is NOT alphabetic\n",c);
}

我可以看到这可能是因为 8 位 ASCII 没有这个字符。

那么我该如何处理 ASCII 表之外的非 ASCII 字符呢?

我想要做的是如果找到任何非字母字符(即使它包含不在 8 位 ASCII 表中的此类字符)我希望能够忽略它。

【问题讨论】:

  • 请注意,'£' 不是 ASCII 字符。您正在混合上下文:结果可能令人惊讶。

标签: c non-ascii-characters


【解决方案1】:

您可能希望将发送到isalpha(以及<ctype.h> 中声明的其他函数)的值转换为unsigned char

isalpha((unsigned char)value)

这是在 C 中适合进行强制转换的少数场合之一。


编辑添加解释。

根据the standard,重点是我的

7.4

1 标题<ctype.h> 声明了几个对分类和映射有用的函数 人物。在所有情况下,参数都是int,其值应为 可表示为unsigned char 或应等于宏EOF 的值。 如果 参数有任何其他值,行为未定义。

转换为unsigned char 确保调用isalpha() 不会调用未定义行为。

【讨论】:

  • 谢谢。字符 c; c='£'; isalpha((无符号字符)(c));确实有效。没有断言并且 isalpha 现在返回 '£' 不是字母。
  • @Alnitak: 呵呵,我没有真正解释任何事情......帖子已编辑
【解决方案2】:

您必须将int 传递给isalpha(),而不是char。注意这个函数的标准原型:

int isalpha(int c);

传递一个 8 位有符号字符将导致该值被转换为负整数,从而导致非法负偏移量进入 isxxxx() 通常使用的内部数组。

但是,您必须确保在转换时将 char 视为 unsigned - 您不能简单地将其直接转换为 int,因为如果它是 8 位字符,则生成的 int 仍然消极。

确保此工作正常的典型方法是将其转换为unsigned char,然后依靠隐式类型转换将其转换为int。

例如

char c = '£';
int a = isalpha((unsigned char) c);

【讨论】:

  • 我不这么认为。即使我尝试过 - int c; c='£';并将它传递给 isalpha(c),它断言。
  • @goldenmean 如果您的默认字符已签名,则仍将传递一个负整数。如果你尝试int c = (unsigned char)'£' 会发生什么?
  • 正如上面回答的pmg,char c; c='£'; isalpha((无符号字符)(c));确实有效。没有断言并且 isalpha 现在返回 '£' 不是字母。
  • @goldenmean 是的,我就是这么说的。
  • 谢谢。 +1 解释
【解决方案3】:

您可能正在使用 wchar (UNICODE) 作为字符类型进行编译,在这种情况下,要使用的 isalpha 方法是 iswalpha

http://msdn.microsoft.com/en-us/library/xt82b8z8.aspx

【讨论】:

  • K 谢谢。现在使用 if(iswalpha(c)) ,它不断言,但现在它将“£”作为字母字符传递,当我只想将字母 ([a..z]) 推导出为字母字符时。
  • @Anders - 现在,除非 Goldenmean 将他的 char 更改为 wchar_t,否则他正在混合 char 和 Unicode,这肯定是不对的。
猜你喜欢
  • 2018-09-05
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 2012-12-08
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多