为什么putchar,toupper,tolower等采用int而不是char?

时间:2013-07-03 16:04:39

标签: c putchar tolower toupper

在C中,字符串是char(char *)数组,字符通常存储在char中。我注意到libC中的一些函数将作为参数整数而不是char。

例如,让我们使用toupper()tolower()两个都使用int的函数。该手册页说:

  

如果c不是无符号字符值或EOF,则表示这些行为   函数未定义。

我的猜测是inttouppertolower能够处理unsigned charEOF。但实际上EOF实际上(有没有关于它的值的规则?)是一个可以用char存储的值,因为这些函数不会将EOF转换成某些东西否则,我想知道为什么toupper不会简单地将char作为参数。

在任何情况下,为什么我们需要接受不属于某个角色的东西(例如EOF)?有人可以给我一个相关的用例吗?

这与fputcputchar类似,但也会将int转换为unsigned char

我正在寻找这种选择的确切动机。我想要被说服,我不想回答我不知道有人有一天会问我。

3 个答案:

答案 0 :(得分:9)

C11 7.4

  

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

C11 7.21.1

  

EOF

     

扩展为整数常量表达式,类型为int和a   负值,......

C标准明确规定 EOF始终为负值的int。此外,默认char类型的签名是实现定义的,因此它可能是无符号的,无法存储负值:

C11 6.2.5

  

如果基本执行字符集的成员存储在char中   对象,其值保证为非负。如果有的话   字符存储在char对象中,结果值为   实现定义但应在值的范围内   可以用那种类型表示。

答案 1 :(得分:2)

BITD包括编码方法:

/* example */
int GetDecimal() {
  int sum = 0;
  int ch;
  while (isdigit(ch = getchar())) { /* isdigit(EOF) return 0 */
    sum *= 10;
    sum += ch - '0';
    }
  ungetc(ch, stdin);  /* If c is EOF, operation fails and the input stream is unchanged. */
  return sum;
}
然后,具有EOF值的

ch可用于isalpha()tolower()等各种函数。

此样式导致putchar(EOF)出现问题,我怀疑它与putchar(255)的问题相同。

由于各种原因,这种方法今天不鼓励。以下各种型号是优选的。

int GetDecimal() {
  int ch;
  while (((ch = getchar()) != EOF)) && isdigit(ch)) {
    ...
  }
  ...
}

答案 2 :(得分:1)

如果c不是无符号字符值或EOF,则这些函数的行为是未定义的。

但是EOF在C中是负int,而某些平台(在ARM!中)charunsigned char相同。