5

中的各种is...函数(例如isalpha, isdigitctype.h并不是完全可预测的。它们接受int参数但期望unsigned char范围内的字符值,因此在有char符号的平台上,直接传递char值可能会导致不希望的符号扩展。我相信处理这个问题的典型方法是明确地转换为unsigned char第一个。

好的,但是处理中的各种isw...功能的正确、可移植的方法是wctype.h什么? wchar_t, like char, 也可以是有符号或无符号的,但因为wchar_t它本身是 a typedef,所以类型名 ofunsigned wchar_t是非法的。

4

2 回答 2

2

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

对于本小节中描述的所有接受类型参数的函数wint_t,其值应可表示为 awchar_t或应等于宏的值WEOF。如果此参数具有任何其他值,则行为未定义。(§7.25.1/5)

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

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

(强调我的)

我认为理解为什么ctype.h函数需要unsigned char表示的动机也是值得的。该标准要求EOF是否定的int(§7.19.1/3),因此ctype.h函数使用unsigned char表示来(尝试)避免潜在的歧义。

相比之下,wctype.h功能不存在这种动机。该标准对 没有这样的要求WEOF,由脚注 270 详细说明:

宏的值WEOF可能与 的不同,EOF不必为负。

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

因此,这些wctype.h函数没有或不需要任何无符号的废话,并且wchar_t可以直接将值传递给它们。

于 2012-05-06T06:03:35.853 回答
2

wint_t就是为了这个吗?iswXxxxx()函数采用以下类型wint_t

ISO 9899:1999 在各个部分中涵盖了这一点,向后工作:

§7.25 宽字符分类和映射实用程序<wctype.h>

§7.25.2.1.1 iswalnum 函数

概要

#include <wctype.h>
int iswalnum(wint_t wc);

描述

iswalnum 函数测试任何 iswalpha 或 iswdigit 为真的宽字符。

§7.24 扩展的多字节和宽字符实用程序<wchar.h>

§7.24.1 简介:

wint_t

它是一个默认不变的整数类型,参数promotions 可以保存对应于扩展字符集成员的任何值,以及至少一个不对应于扩展字符集任何成员的值(参见下面的WEOF);269)

269) wchar_t并且wint_t可以是相同的整数类型。

“默认情况下不变的参数提升”应该意味着它必须和 a 一样大int,尽管它可能是 ashortunsigned shortif sizeof(short) == sizeof(int)(现在很少出现这种情况,尽管对于某些 16 位系统来说确实如此)。

§7.17 通用定义<stddef.h>

wchar_t

这是一个整数类型,其值范围可以表示支持的语言环境中指定的最大扩展字符集的所有成员的不同代码;空字符的代码值为零,基本字符集的每个成员在用作整数字符常量中的唯一字符时,其代码值应等于其值。

只要传递给iswalnum()或其亲属的值是有效的wchar_t或 WEOF,该函数就会正常工作。如果您凭空制造了价值并设法弄错了价值,那么您将获得未定义的行为。

于 2012-05-06T05:34:46.207 回答