如何正确使用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