如何正确使用wctype.h函数?

如何正确使用wctype.h函数?,c,language-lawyer,ctype,C,Language Lawyer,Ctype,ctype.h中的各种is…功能(例如isalpha,isdigit)不是完全可预测的。它们接受int参数,但期望字符值在无符号字符范围内,因此在char有符号的平台上,直接传递char值可能会导致不需要的符号扩展。我认为处理这个问题的典型方法是首先显式地强制转换为无符号字符 好的,但是处理wctype.h中的各种isw…函数的合适的、可移植的方法是什么wchar\u t,就像char一样,也可以是有符号的或无符号的,但是因为wchar\u t本身就是一个typedef,所以无符号wchar\u

ctype.h
中的各种
is…
功能(例如
isalpha
isdigit
)不是完全可预测的。它们接受
int
参数,但期望字符值在
无符号字符
范围内,因此在
char
有符号的平台上,直接传递
char
值可能会导致不需要的符号扩展。我认为处理这个问题的典型方法是首先显式地强制转换为
无符号字符


好的,但是处理
wctype.h
中的各种
isw…
函数的合适的、可移植的方法是什么
wchar\u t
,就像
char
一样,也可以是有符号的或无符号的,但是因为
wchar\u t
本身就是一个
typedef
,所以
无符号wchar\u t
的类型名是非法的。

这不是
wint
的目的吗?
iswXxxxx()
函数采用
wint\t
类型:

ISO 9899:1999在不同的章节中介绍了这一点,向后工作:

§7.25宽字符分类和映射实用程序
§7.25.2.1.1 iswalnum功能 概要

#include <wctype.h>
int iswalnum(wint_t wc);
它是一个整数类型,默认情况下保持不变,可以保存任何 与扩展字符集的成员相对应的值,以及至少一个 与扩展字符集的任何成员都不对应的值(请参见WEOF) 下);(269)

269)
wchar\u t
wint\u t
可以是相同的整数类型

“默认参数升级未更改”应该意味着它必须与
int
一样大,尽管它可以是
short
unsigned short
,如果
sizeof(short)==sizeof(int)
(目前这种情况很少发生,尽管对于某些16位系统是如此)

§7.17通用定义
这是一种整数类型,其值范围可以表示所有类型的不同代码 支持的区域设置中指定的最大扩展字符集的成员;这个 空字符的代码值应为零,且基本字符集的每个成员 当用作整数中的单个字符时,其代码值应等于其值 字符常量


只要传递给
iswalnum()
或其kin的值是有效的
wchar\u t
或WEOF,函数就会正常工作。如果您凭空制造了值,并设法将值弄错,则会出现未定义的行为。

在重新阅读有关
wctype.h
的ISO C99规范时,它指出:

对于本子条款中描述的所有接受
wint\u t
类型参数的函数,该值应表示为
wchar\u t
,或应等于宏
WEOF
的值。如果此参数具有任何其他值,则行为未定义。(§7.25.1/5)

将此与
ctype.h
的相应注释进行对比:

在所有情况下,参数都是
int
,其值应为 可表示为
无符号字符
或应等于宏
EOF
的值。如果参数有任何其他值,则行为未定义。(§7.4/1)

(强调矿山)

我认为理解
ctype.h
函数需要
无符号字符
表示的动机也是值得的。该标准要求
EOF
为负
int
(§7.19.1/3),因此
ctype.h
函数使用
无符号字符
表示来避免潜在的歧义

相反,
wctype.h
函数不存在这种动机。本标准未对
WEOF
作出此类要求,脚注270详述了该要求:

WEOF
的值可能不同于
EOF
的值,并且不需要为负值

因为
WEOF
已经保证不会与
wchar_t
所表示的任何字符冲突(§7.24.1/3)


因此,
wctype.h
函数没有或不需要任何无符号无意义,并且可以将
wchar\u t
值直接传递给它们。

为什么符号扩展有问题?@Mat:
是…
函数期望值在
无符号字符
范围内。如果您给它们一个不同的值,您将得到未定义的行为。一个具体的例子是,如果您的字符值恰好是
-1
,它很可能会被视为
EOF
。很好,我从来没有意识到它们是这样指定的。@JaimeOlivares:嗯?如果你将
0xFF
存储在一个有符号的
char
中,那么当它被提升到32位
int
时,它将变成
0xffffff
@JaimeOlivares:No.
char
可能有符号,也可能无符号,这取决于平台。我并不完全明白。升级时,
wint\u t
保持不变并不意味着升级到
wint\u t
时,
wchar\u t
保持不变。正常的
是…
函数采用
int
而不是
char
isw…
函数类似地采用
wint\t
而不是
wchar\t
。第二个案例的不同之处是什么?好吧,仔细考虑你的参考资料,我找到了正确的方向,我想我现在知道为什么这两个案例不完全相似了。(见我对自己问题的回答。)
wint_t
wchar_t