wchar_t 和编码
Posted
技术标签:
【中文标题】wchar_t 和编码【英文标题】:wchar_t and encoding 【发布时间】:2012-05-13 10:59:36 【问题描述】:如果我想将一段字符串转换为 UTF-16,比如char * xmlbuffer
,是否必须在编码为 UTF-16 之前将类型转换为 wchar_t *
?在编码为 UTF-8 之前是否需要 char*
类型?
wchar_t
、char
与 UTF-8 或 UTF-16 或 UTF-32 或其他转换格式有何关系?
提前感谢您的帮助!
【问题讨论】:
【参考方案1】:不,您不必更改数据类型。
关于wchar_t
:标准是这样说的
类型 wchar_t 是一个 distinct 类型,其值可以表示 distinct 指定的最大扩展字符集的所有成员的代码 在受支持的语言环境中。
不幸的是,它没有说明wchar_t
应该有什么编码;这取决于实现。所以例如给定
auto s = L"foo";
您绝对不能对表达式 *s
的值做出任何假设。
但是,您可以将std::string
用作不透明的字节序列,以您选择的任何转换格式表示文本,而不会出现问题。只是不要对其执行标准库字符串相关的操作。
【讨论】:
那么我能说在windows平台使用wchar_t转UTF-16只是为了方便的选择,理论上绝对可以用char转UTF-16? @Hunter:理论上是的,但在 Windows 中,wchar_t
用于 UTF-16,char
用于 ASCII 和 UTF-8。
在 Windows 上,wchar_t
的已知大小为 16 位
@Hunter,如果您在 UTF-16 字符串上调用 strlen
,它可能总是返回 0 或 1。strlen
只接受 8 位字符,并且会在第一个字符处停止高字节为 0。
@Mooing Duck:char16_t
更好,但只是最近才添加到 C++ 标准中。【参考方案2】:
iconv
是一个 POSIX 函数,可以处理中间编码步骤。您可以使用 iconv_open
指定您有 UTF-8 输入并且您想要 UTF-16 输出。然后,使用从iconv_open
返回的句柄,您可以使用iconv
(指定您的输入缓冲区和输出缓冲区)。完成后,您必须在从 iconv_open
返回的句柄上调用 iconv_close
以释放资源等。
您必须仔细阅读系统文档,了解iconv
支持哪些编码及其命名方案(即提供iconv_open
的内容)。例如,某些系统上的iconv
需要"utf-8"
,而其他系统可能需要"UTF8"
等。
Windows 不提供 iconv 版本,而是提供了自己的 UTF 格式化函数:MultiByteToWideChar 和 WideCharToMultiByte。
//UTF8 to UTF16
std::string input = ...
int utf16len = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), input.size(),
NULL, 0);
std::wstring output(utf16len);
MultiByteToWideChar(CP_UTF8, 0, input.c_str(), input.size(),
&output[0], output.size());
//UTF16 to UTF8
std::wstring input = ...
int utf8len = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), input.size(),
NULL, 0, NULL, NULL);
std::string output(utf8len);
WideCharToMultiByte(CP_UTF8, 0, input.c_str(), input.size(),
&output[0], output.size(), NULL, NULL);
【讨论】:
Hunter:注意Windows没有自带iconv,但是有办法得到。 @Dreamlax:您介意我们将我的答案作为 Windows 替代方案插入您的答案并删除我的答案吗?使用库的概念是正确的,您对此更清楚。 @MooingDuck:是的,绝对是,听起来是个好主意。将我的放入您的或您的放入我的,无论哪个。【参考方案3】:wchar_t
的大小取决于编译器,因此它与各种 unicode 格式的关系会有所不同。
【讨论】:
以上是关于wchar_t 和编码的主要内容,如果未能解决你的问题,请参考以下文章