【问题标题】:wcstombs: character encoding?wcstombs:字符编码?
【发布时间】:2011-01-12 12:12:57
【问题描述】:

wcstombs documentation 说,它“将宽字符代码序列转换为多字节字符串”。但它从来没有说什么是“宽字符”。

它是隐式的,比如将 utf-16 转换为 utf-8 还是由某个环境变量定义的转换?

wcstombs 的典型用例是什么?

【问题讨论】:

  • “宽字符”是wchar_t

标签: c character-encoding


【解决方案1】:

您使用setlocale() 标准函数和LC_CTYPE(或LC_ALL)类别来设置库在wchar_t 字符和多字节字符之间使用的映射。传递给 setlocale() 的实际语言环境名称是实现定义的,因此您需要在编译器的文档中查找它。

例如,你可以使用 MSVC

setlocale( LC_ALL, ".1252" );

将 C 运行时设置为使用代码页 1252 作为多字节字符集。请注意,MSVC 文档明确指出,对于多字节字符集,区域设置不能设置为 UTF-7 或 UTF8:

可用语言、国家/地区代码和代码页集包括 Win32 NLS API 支持的所有语言,但每个字符需要两个以上字节的代码页除外,例如 UTF-7 和 UTF-8。如果您提供像 UTF-7 或 UTF-8 这样的代码页,setlocale 将失败,返回 NULL。

“宽字符”wchar_t 类型旨在能够支持系统支持的任何字符集 - 标准没有定义 wchar_t 类型的大小(它可以像 @ 987654329@ 或任何更大的整数类型)。在 Windows 上,它是系统的“内部”Unicode 编码,即 UTF-16(WinXP 之前的 UCS-2)。不过,老实说,我在 MSVC 文档中找不到直接引用。严格来说,实现应该调用这个,但我找不到。

【讨论】:

  • 警告:setlocale 中的语言环境字符串没有标准,所以跨平台做任何事情都不容易。例如 .1252 在 Windows 上有效,但在 UNIX/Linux 上无效(在那里你会看到像 en_US.UTF-8 或 en_US.iso889-1 这样的东西)
【解决方案2】:

宽字符串由多字节字符组成,而普通的 C 字符串是 char* - 字节宽字符序列。 wchars 与所有平台上的 unicode 不同,尽管 unicode 表示通常基于 wchar_t

我已经看到 wchars 在嵌入式系统(如手机)中使用,您希望文件名带有特殊字符,但不一定要支持 unicode 的所有荣耀和复杂性。

典型用法是将基于 2 字节的字符串转换为常规 C 字符串,反之亦然

【讨论】:

  • 这可能有点令人困惑 - 在这个和类似的用法中,“多字节字符串”是由字符组成的字符串 - 一个“标准 ansi c 字符串”,但可能还有更多每个逻辑字符超过一个字符(字节),而宽字符串通常为每个元素分配超过 1 个字节(sizeof(wchar_t)==2 很常见),通常最初错误地认为这将允许在一个字符串到相等数量的元素。
【解决方案3】:

它将您的平台用于“宽字符”的任何内容(我相信在 Windows 上确实是 UCS2,但在 UNIX 上通常是 UCS4)转换为您当前语言环境的默认多字节字符编码。如果您的语言环境是 UTF-8,那么这就是将使用的多字节编码 - 但请注意还有其他可能性,例如 JIS。

【讨论】:

  • 在 UTF-16 而非 UCS2 的 Windows 上。
  • 很公平。 (这似乎有点坏了——widechars 的全部意义应该是一个widechar 总是一个字符)。
  • 这绝不是真的。即使是 Linux 上的 32 位宽字符也可能表示非打印元素,例如分解的重音字符的一部分、RTL 排序指令或各种其他东西。因此,无论编码如何,假设一个代码点是一个字符是绝对不安全的。
【解决方案4】:

根据 C 标准,wchar_t 类型是“能够表示当前语言环境中的任何字符”。该标准没有说明wchar_t 的编码是什么。实际上,WCHAR_MINWCHAR_MAX 的限制是 [0, 255] 或 [-127, 127],这取决于 wchar_t 是无符号还是有符号。

一个多字节字符可以使用多个字节。多字节字符串由一个或多个多字节字符组成。在多字节字符串中,每个字符的字节数不必相等(UTF-8 就是一个例子)。而wchar_t 类型的对象具有固定大小(当然,在给定的实现中)。

顺便说一句,我还可以在我的 C99 草案副本中找到以下内容:

__STDC_ISO_10646__ yyyymmL 形式的整数常量(例如,199712L)。如果定义了此符号,则 Unicode 所需集中的每个字符在存储在 wchar_t 类型的对象中时,都具有与该字符的短标识符相同的值。 Unicode 要求集包含 ISO/IEC 10646 定义的所有字符,以及截至指定年份和月份的所有修订和技术勘误。

所以,如果我理解正确的话,如果__STDC_ISO_10646__被定义,那么wchar_t可以存储Unicode字符。

【讨论】:

  • WCHAR_MAX 的实际限制不是255(您可能与char 类型混淆)。根据c11c99也有同样的描述):value of **WCHAR_MAX** shall be no less than 255.。实际值可能是2147483647。现场示例here。我从来没见过是不是255
猜你喜欢
  • 2018-03-24
  • 2011-08-03
  • 1970-01-01
  • 2011-05-31
  • 2011-03-02
  • 2013-12-29
  • 2011-01-17
  • 1970-01-01
相关资源
最近更新 更多