【问题标题】:Why do ctype functions take int but want unsigned char/EOF?为什么 ctype 函数需要 int 但需要 unsigned char/EOF?
【发布时间】:2012-07-24 04:04:37
【问题描述】:

我正在使用 gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

isalnum() 的手册页说:

SYNOPSIS
       #include <ctype.h>

       int isalnum(int c);

但是,它也说:

这些函数检查是否 c, 必须有一个值 无符号字符或EOF,...

我发现isalnum() 会因为非常大的正(或负)int 值而爆炸(但它会处理所有short int 值)。

手册页是否说传入的 int 必须具有 unsigned char 的值,因为 C 库编写者保留以不会处理所有 int 值而不爆炸的方式实现 isalnum() 的权利?

【问题讨论】:

  • 是的,就是这么说的。

标签: c


【解决方案1】:

C 标准说了这么多......

在 ISO/IEC 9899:1999(旧的 C 标准)中,它说:

§7.4 字符处理

标头声明了几个对分类和映射有用的函数 人物。在所有情况下,参数都是一个 int,其值应为 可表示为无符号字符或应等于宏 EOF 的值。如果 参数有任何其他值,行为未定义。

我遗漏了一个脚注。)C89 和 C11 说的非常相似。

一种常见的实现是使用偏移 1 的数组——主题的变体:

int _CtypeBits[257] = { ... };

#define isalpha(c)  (_Ctype_bits[(c)+1]&_ALPHA);

只要cunsigned char 可以存储的整数范围内(并且每个字符有8 位,EOF 为-1,并且初始化正确),那么它就可以很好地工作。请注意,宏扩展只使用一次参数,这是标准的另一个要求。但是,如果您将随机值传递到规定范围之外,您将访问随机内存(或者,至少是未初始化以包含正确信息的内存)。

【讨论】:

  • 更好的实现是#define isalpha(c) (((unsigned)(c)|32)-'a'&lt;26)。 :-)
  • 感谢乔纳森!似乎他们应该有一个额外的免责声明,如果他们想在你的例子中实现它并且是准确的:“,并且 EOF 必须定义为 -1”。
  • @R.:除了仅适用于 C 语言环境,而使用 Jonathan 的方法,根据当前语言环境切换数组是微不足道的。但我当然知道你知道 ;)
  • 实际上它也适用于任何 UTF-8 语言环境,因为前 128 个字节与 ASCII 匹配,其余字节本身不代表字符(因此需要 isw* 函数)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
  • 2019-07-24
  • 2019-03-11
  • 2015-11-07
  • 2013-10-30
  • 2019-06-09
相关资源
最近更新 更多