代码之家  ›  专栏  ›  技术社区  ›  Dervin Thunk

wchar_t与wint_t

  •  11
  • Dervin Thunk  · 技术社区  · 15 年前

    这是一个ANSI C问题。我有以下代码。

    #include <stdio.h>
    #include <locale.h>
    #include <wchar.h>
    
      int main()
      {
        if (!setlocale(LC_CTYPE, "")) {
          printf( "Can't set the specified locale! "
                  "Check LANG, LC_CTYPE, LC_ALL.\n");
          return -1;
        }
        wint_t c;
        while((c=getwc(stdin))!=WEOF)
          {
        printf("%lc",c);
          }
        return 0;
      }
    

    我需要完整的UTF-8支持,但即使在这个最简单的级别上,我能以某种方式改进它吗?为什么是 wint_t 使用,而不是 wchar ,是否进行了适当的更改?

    3 回复  |  直到 15 年前
        1
  •  3
  •   MestreLion    9 年前

    UTF-8 是Unicode的一种可能编码。它定义每个字符1、2、3或4个字节。当你读完它 getwc() ,它将获取一到四个字节,并从中组合一个Unicode字符。 代码点 ,它将适合 wchar (根据平台的不同,宽度可以是16位甚至32位)。

    但由于Unicode值映射到 0x0000 0xFFFF ,中没有返回条件或错误代码的值。(有些人指出Unicode大于16位,这是正确的;在这种情况下 surrogate pairs 被使用。但这里的重点是Unicode使用 全部的 可用值中的一个,不留用于EOF。)

    各种错误代码包括EOF( WEOF ,映射到-1。如果你把 GETWC() 在一个 瓦查 无法将其与Unicode区分开来。 0xFFFF 字符(顺便说一句,这是保留的,但我离题了)。

    所以答案是使用 更广的 类型 wint_t (或) int ,其中至少包含32位。它给出了实际值的低16位,并且任何设置在该范围之外的位都意味着发生了字符返回以外的事情。

    为什么我们不经常使用 瓦查 那么,而不是 wint ?大多数与字符串相关的函数使用 瓦查 因为在大多数平台上,它的尺寸是 温特 ,所以字符串的内存占用较小。

        2
  •  16
  •   Brandon E Taylor    15 年前

    wint_t 能够存储的任何有效值 wchar_t . 一 温茨特 也能够接受评估 WEOF 宏(注意 瓦查特 太窄,无法容纳结果)。

        3
  •  6
  •   MestreLion    9 年前

    正如@musiphil在他的评论中所说的那样,我将尝试在这里扩展,这里有一个 概念的 两者之间的差异 wint_t wchar_t .

    它们的大小不同是一个技术方面,这是由于它们各自具有非常独特的特性 语义 :

    • 瓦查特 足够大可以存放 文字 代码点 如果你愿意的话。因此,他们是 未签名的 . 它们类似于 char 在几乎所有的平台中,该值仅限于8位256值。如此宽的字符字符串 变量 自然是这种类型的数组或指针。

    • 现在输入字符串 功能 ,其中一些需要能够返回 任何 瓦查特 外加 状态 . 所以他们的返回类型 必须 大于 瓦查特 . 所以 温茨特 使用,它可以表示任何宽字符,并且 WEOF . 作为一种状态,它也可以 消极的 (通常是),因此 温茨特 最有可能 签署 . 我说“可能”,因为C标准没有 授权 是的。但是不管符号是什么,状态值都必须是 外部 范围 瓦查特 . 它们只是用作返回谷,而不是用来 商店 这样的人物。

    与“经典”的类比 烧焦 int 很好地消除任何混淆:字符串不是类型 int [] 他们是 char var[] (或) char *var )并不是因为 烧焦 “一半大小 int 但是因为那是一根绳子 .

    您的代码看起来正确: c 用于检查 getwch() 就是这样 温茨特 . 如果它的价值不是 韦弗 作为你的 if 测试,然后将它安全地分配给 瓦查特 字符(或字符串数组、指针等)