【问题标题】:Why isn't wchar_t widely used in code for Linux / related platforms?为什么 wchar_t 没有广泛用于 Linux / 相关平台的代码?
【发布时间】:2011-06-03 01:32:28
【问题描述】:

这让我很感兴趣,所以我要问 - 为什么wchar_t 在 Linux/Linux 类系统上没有像在 Windows 上那样广泛使用?具体来说,Windows API 在内部使用wchar_t,而我相信Linux 没有,这反映在许多使用char 类型的开源包中。

我的理解是,给定一个字符c,它需要多个字节来表示它,然后在char[] 形式中c 被拆分为char* 的几个部分,而它在wchar_t[] 中形成一个单元.那么,总是使用wchar_t 不是更容易吗?我是否错过了否定这种差异的技术原因?还是只是收养问题?

【问题讨论】:

    标签: c unicode wchar-t


    【解决方案1】:

    第一个在基于 Unix 的平台上使用 UTF-8 的人explained

    Unicode 标准 [当时是 1.1 版] 定义了一个 足够的字符集,但 不合理的表示 [UCS-2]。它指出 所有字符都是 16 位宽 [不再正确] 并以 16 位单元进行通信和存储。 它还保留了一对 字符数(十六进制 FFFE 和 FEFF) 来检测字节顺序 传输的文本,需要状态 字节流。 (统一码 联盟在考虑文件,而不是 管道。)为了采用这种编码,我们 将不得不转换所有文本 进出Plan 9之间 ASCII 和 Unicode,不能 完毕。在单个程序中,在 命令其所有输入和输出, 可以将字符定义为 16 位数量; 在上下文中 拥有数百个网络的系统 在不同机器上的应用 不同的制造商 [斜体是我的],它是 不可能。

    斜体部分与 Windows 系统的相关性较低,Windows 系统偏好单一应用程序(Microsoft Office)、非多样化机器(一切都是 x86,因此是 little-endian)和单一操作系统供应商。

    拥有小型、单一用途的程序的 Unix 理念意味着更少的程序需​​要进行认真的字符操作。

    我们工具的来源和 申请已经 转换为使用 Latin-1,所以它 是“8 位安全”,但转换 Unicode 标准和 UTF[-8] 是 更多地参与。有些程序不需要 完全改变:cat,例如, 解释其参数字符串, 以 UTF[-8] 传递,作为文件名 它未经解释地传递给 open 系统调用,然后只是复制 从输入到输出的字节数;它 从不根据 字节的值...大多数程序, 但是,需要进行适度的更改。

    ...实际上需要操作的工具很少 关于符文 [Unicode 代码点] 内部;更典型的是他们需要 只在 a 中寻找最后的斜线 文件名和类似的琐碎任务。 在 170 个 C 源程序中……只有 23 个 现在包含单词Rune

    存储符文的程序 内部主要是那些 存在的理由是性格 操作:sam(文本编辑器), sedsorttrtroff(窗口 系统和终端仿真器),等等 在。决定是否计算使用 符文或 UTF 编码的字节字符串 需要平衡成本 在读取和转换数据时 写在转换成本上 按需提供相关文本。对于程序 比如运行时间长的编辑器 具有相对恒定的数据集, 符文是更好的选择...

    UTF-32 可以直接访问代码点,如果您需要类别和大小写映射等字符属性,确实更方便。

    但是 Widechars 在 Linux 上使用起来很尴尬,原因与 UTF-8 在 Windows 上使用起来很尴尬一样。 GNU libc 没有_wfopen_wstat 函数。

    【讨论】:

      【解决方案2】:

      UTF-8 与 ASCII 兼容,可以在一定程度上忽略 Unicode。

      通常,程序并不关心(事实上,也不需要关心)输入是什么,只要不存在可以终止字符串的 \0 即可。见:

      char buf[whatever];
      printf("Your favorite pizza topping is which?\n");
      fgets(buf, sizeof(buf), stdin); /* Jalapeños */
      printf("%s it shall be.\n", buf);
      

      我发现需要 Unicode 支持的唯一情况是我必须将多字节字符作为一个单元 (wchar_t);例如当必须计算字符串中的字符数而不是字节数时。 iconv 从 utf-8 到 wchar_t 将很快做到这一点。对于像零宽度空间和组合变音符号这样的更大问题,需要像 icu 这样更重的东西——但你多久会这样做一次?

      【讨论】:

      • 比较常见的是不区分大小写的比较。但 Linux 不需要它作为文件名。
      • @dan04:无论如何,不​​区分大小写的比较是有问题的,因为正确地进行比较意味着取决于语言环境/文化(例如,土耳其语中的大写 i 不是 I)...这就是为什么唯一合理的选择是区分大小写,IMO。
      【解决方案3】:

      wchar_t 在所有平台上的大小都不相同。在 Windows 上,它是一个使用两个字节的 UTF-16 代码单元。在其他平台上,它通常使用 4 个字节(对于 UCS-4/UTF-32)。因此,这些平台不太可能标准化使用 wchar_t,因为这会浪费大量空间。

      【讨论】:

      • 嗯,它也可以是一个 UTF-16 代理对。
      • wchar_t 中存储代理不仅不符合标准,而且无法使用标准库mbrtowc 实现UTF-8 多字节编码或任何支持非BMP 字符的多字节编码功能。见stackoverflow.com/questions/3228828/…
      • ISO C 修正 1. wchar_t 使用的字符集是故意未指定的,但无论如何,wchar_t 需要足够大以表示任何字符。所以 UCS-2 和 UTF-32 是可以接受的wchar_t 编码,但 UTF-16 不是。
      • 为什么wchar_t 不能接受 UTF-16?只要您将“字符”解释为代码单元而不是代码点,它就可以正常工作。 UTF-16 编码的字符串,即使是使用代理的字符串,也可以用wchar_t 表示,只要每个代码单元在字符串中都有自己的wchar_t 元素。
      • @Remy:因为mbrtowc 函数不能按照指定的方式运行,当单个多字节字符必须转换为两个或多个wchar_t 值时。请参阅我链接的问题。
      【解决方案4】:

      wchar_t 是一个具有平台定义宽度的宽字符,它并没有太大帮助。

      UTF-8 字符跨越每个字符 1-4 个字节。 UCS-2,每个字符正好跨越 2 个字节,现在已经过时,不能代表完整的 Unicode 字符集。

      支持 Unicode 的 Linux 应用程序倾向于在字节存储层之上正确执行此操作。 Windows 应用程序倾向于做出这种愚蠢的假设,即只有两个字节可以。

      wchar_t's Wikipedia article 简要介绍了这一点。

      【讨论】:

      • Windows 使用 UTF-16,它不会假设两个字节就足够了。 UTF-16 可以代表整个 Unicode。 UTF-16's Wikipedia article 简要介绍了这一点:-)
      • 另一方面,许多 Linux 应用程序做出“愚蠢的假设”,即 UTF-8 意味着它们无需更改任何内容即可使其代码正确运行。 unicode 标准,仍然可以在任何地方使用普通的char *s 而不用关注事物。
      • @Joey:是的,这就是为什么 windows UTF-16 最终不比 UTF-8 好:你无法预测字符大小。从此以后,您不能在字符串中移动给定数量的字符。那么在写英文信息时使用两倍的空间有什么意义呢?
      • @kriss @Tomalak @Joey:请记住,将“Unicode”添加到 Win32 时,2 个字节足以编码任何代码点。 (NT3.51 早在 1996 年之前就已经发布了,当时引入了 UTF-16)这就是 Windows 现在使用 UTF-16 的原因——他们已经决定使用 wchar_t,而且他们无法破坏整个 API。此外,即使您的应用仅使用 UCS-2,您仍然可以毫无困难地对大多数现代使用的语言进行编码。
      • @kriss:遗产。 Windows 从一开始就使用 UCS-2,而转向 UTF-16 是最明智的做法。 Java 在这方面也有类似的遗产。那时,UCS-2可以代表所有 Unicode,代码单元和代码点是等效的——这本身就是一件非常好的事情,无论文本的存储要求如何(Unicode 文本很可能不是占用硬盘空间的最大部分)。因此,为什么做出这样的设计选择也就不足为奇了。 (继续阅读)
      猜你喜欢
      • 1970-01-01
      • 2014-02-18
      • 2013-01-07
      • 2012-08-23
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多