【发布时间】:2011-01-12 12:12:57
【问题描述】:
wcstombs documentation 说,它“将宽字符代码序列转换为多字节字符串”。但它从来没有说什么是“宽字符”。
它是隐式的,比如将 utf-16 转换为 utf-8 还是由某个环境变量定义的转换?
wcstombs 的典型用例是什么?
【问题讨论】:
-
“宽字符”是
wchar_t。
标签: c character-encoding
wcstombs documentation 说,它“将宽字符代码序列转换为多字节字符串”。但它从来没有说什么是“宽字符”。
它是隐式的,比如将 utf-16 转换为 utf-8 还是由某个环境变量定义的转换?
wcstombs 的典型用例是什么?
【问题讨论】:
wchar_t。
标签: c character-encoding
您使用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 文档中找不到直接引用。严格来说,实现应该调用这个,但我找不到。
【讨论】:
宽字符串由多字节字符组成,而普通的 C 字符串是 char* - 字节宽字符序列。 wchars 与所有平台上的 unicode 不同,尽管 unicode 表示通常基于 wchar_t
我已经看到 wchars 在嵌入式系统(如手机)中使用,您希望文件名带有特殊字符,但不一定要支持 unicode 的所有荣耀和复杂性。
典型用法是将基于 2 字节的字符串转换为常规 C 字符串,反之亦然
【讨论】:
它将您的平台用于“宽字符”的任何内容(我相信在 Windows 上确实是 UCS2,但在 UNIX 上通常是 UCS4)转换为您当前语言环境的默认多字节字符编码。如果您的语言环境是 UTF-8,那么这就是将使用的多字节编码 - 但请注意还有其他可能性,例如 JIS。
【讨论】:
根据 C 标准,wchar_t 类型是“能够表示当前语言环境中的任何字符”。该标准没有说明wchar_t 的编码是什么。实际上,WCHAR_MIN 和 WCHAR_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 类型混淆)。根据c11(c99也有同样的描述):value of **WCHAR_MAX** shall be no less than 255.。实际值可能是2147483647。现场示例here。我从来没见过是不是255。