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

Posted

技术标签:

【中文标题】将 wchar_t* 转换为 UTF-16 字符串【英文标题】:Convert wchar_t* to UTF-16 string 【发布时间】:2012-03-30 15:09:03 【问题描述】:

我需要一个 C++ 代码来将wchar_t* 中给出的字符串转换为 UTF-16 字符串。它必须同时在 Windows 和 Linux 上运行。我在搜索过程中浏览了很多网页,但我仍然不清楚主题。

据我了解,我需要:

    使用 LC_TYPE 和 UTF-16 编码调用 setlocale。 使用wcstombswchar_t 转换为UTF-16 字符串。 致电setlocale 恢复以前的语言环境。

你知道我可以通过什么方式将wchar_t* 以可移植的方式(Windows 和 Linux)转换为 UTF-16 吗?

【问题讨论】:

也许我的编码相关问题#1、#2、#3 有一些用处。 wchar_t 字符串在哪个代码集中?您希望使用什么类型来表示 UTF-16 字符串中的字符类型?这仅仅是 UTF-32(在wchar_t 中)和 UTF-16 在uint16_t 中的转换吗?还是您也在处理代码集转换?可移植性是一个崇高的目标;可悲的是,这并不总是可以实现的。一定要调查ICU。 【参考方案1】:

在 C++03 中没有单一的跨平台方法可以做到这一点(不是没有库)。这部分是因为wchar_t 本身在不同平台上并不相同。在 Windows 下,wchar_t 是一个 16 位的值,而在其他平台上它通常是一个 32 位的值。所以你需要两个不同的代码路径来做到这一点。

【讨论】:

【参考方案2】:

我认为 C++11 的 std::codecvt_utf16 应该可以工作。

std::codecvt_utf16 是一个 std::codecvt facet,它封装了 UTF-16 编码的字节字符串和 UCS2 或 UCS4 字符串之间的转换(取决于 Elem 的类型)。

看到这个:http://en.cppreference.com/w/cpp/locale/codecvt_utf16

【讨论】:

一切都很好,除了 G++(或更准确地说,libstdc++)还没有提供<codecvt> 标头,所以std::codecvt_utf16 不可用。 C++11 还引入了char16_tchar32_t 类型(以及相关的std::basic_string typedefs)以摆脱wchar_t 平台问题。例如,在需要 UTF-16 编码字符串的地方使用 std::u16string【参考方案3】:

您可以假设 wchar_t 在非 Windows 世界中是 utf-32。在 Linux 和 Mac OS X 以及大多数 *nix 系统上确实如此(很少有例外,在您可能永远不会接触的系统上:-)

而 wchar_t 在 Windows 上是 utf-16。所以在 Windows 上,转换函数可以做一个 memcpy :-)

在其他所有方面,转换都是算法性的,而且非常简单。所以不需要第三方库的花哨支持。

这里是基本算法:http://unicode.org/faq/utf_bom.html#utf16-3

如果您不想自己编写,您可能会找到十几种不同的实现:-)

【讨论】:

【参考方案4】:

问题在于wchar_t 指定不足。你可以使用 GNU libiconv 来做你想做的事。它接受特殊编码名称"wchar_t" 作为源编码和目标编码。这样它就可以移植到 Windows 和 Linux 以及您可以提供 libiconv 的其他地方。

【讨论】:

【参考方案5】:

g++ 编译器似乎支持 wcstombs?

【讨论】:

您是在问问题还是在陈述事实?

以上是关于将 wchar_t* 转换为 UTF-16 字符串的主要内容,如果未能解决你的问题,请参考以下文章

wchar_t 和编码

在wstring到str转换的CPP问题

为啥我不能将带有破折号的字符串转换为 wstring?

如何读取 UTF-16 文件并将其内容与使用十六进制值定义的 wchar_t* 字符串文字进行比较

C++ 标准是不是要求对 wchar_t 进行编码?

将 wchar_t* 转换为字符串 [重复]