【问题标题】:How are wctype.h functions supposed to be used correctly?wctype.h 函数应该如何正确使用?
【发布时间】:2012-05-06 05:15:44
【问题描述】:

ctype.h 中的各种 is... 函数(例如 isalphaisdigit)并非完全可预测。它们采用int 参数,但期望在unsigned char 范围内的字符值,因此在char 被签名的平台上,直接传递char 值可能会导致不需要的符号扩展。我相信处理这个问题的典型方法是首先明确地转换为unsigned char

好的,但是处理wctype.h 中的各种isw... 函数的正确、可移植的方法是什么? wchar_tchar 一样,也可以是有符号或无符号的,但因为wchar_t 本身就是一个typedef,所以unsigned wchar_t 的类型名是非法的。

【问题讨论】:

  • 为什么符号扩展是个问题?
  • @Mat:is... 函数需要在unsigned char 范围内的值。如果你给它们一个不同的值,你会得到未定义的行为。一个具体的例子是,如果你的字符值恰好是-1,它很可能会被视为EOF
  • 好点,我从来没有意识到他们是这样指定的。
  • @JaimeOlivares:嗯?如果您将0xFF 存储在签名的char 中,那么当它被提升为例如32 位int 时,它将变为0xFFFFFFFF
  • @JaimeOlivares: 否。char 可能已签名或未签名,具体取决于平台。

标签: c language-lawyer ctype


【解决方案1】:

这不是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 扩展多字节和宽字符实用程序&lt;wchar.h&gt;

§7.24.1 简介:

wint_t

这是一个整数类型,默认情况下不变,参数提升可以容纳任何 对应于扩展字符集成员的值,以及至少一个 与扩展字符集的任何成员都不对应的值(请参阅 WEOF 下面);269)

269)wchar_twint_t 可以是相同的整数类型。

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

§7.17 通用定义&lt;stddef.h&gt;

wchar_t

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

只要传递给iswalnum() 或其亲属的值是有效的wchar_t 或WEOF,函数就会正常工作。如果你凭空制造了价值并设法弄错了价值,你就会得到不确定的行为。

【讨论】:

  • 我并不完全关注。 wint_t 升级后未更改并不意味着 wchar_t 在升级到 wint_t 时未更改。正常的is... 函数采用int 而不是charisw... 函数类似地采用 wint_t 而不是 wchar_t。是什么让第二种情况不同?
  • 好的,思考你的参考资料让我找到了正确的方向,我想我现在知道为什么这两个案例不完全相似了。 (请参阅我对自己问题的回答。)
【解决方案2】:

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

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

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

在所有情况下,参数都是int,其值应为 可表示为 unsigned 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 值可以直接传递给它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 2021-02-03
    相关资源
    最近更新 更多