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_tchar 与 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 和编码的主要内容,如果未能解决你的问题,请参考以下文章

交替读取为 char* 和 wchar_t*

wchar_t类型的几个函数

将 wchar_t* 转换为 UTF-16 字符串

IO库中的宽字符语言

wchar_t到QString的转换方法?

CString 如何转为wchar_t