如何使用 <codecvt> 转换 std::u16string -> std::wstring?
how does one convert std::u16string -> std::wstring using <codecvt>?
我发现了一堆关于类似主题的问题,但没有关于使用 <codecvt>
进行宽到宽转换的问题,这应该是现代代码中的正确选择。
std::codecvt_utf16<wchar_t>
似乎是执行转换的合乎逻辑的选择。
然而,std::wstring_convert
似乎期望 std::string
一方面。方法 from_bytes
和 to_bytes
强调了这个目的。
我的意思是,到目前为止最好的解决方案是 std::copy
,它可能适用于我的具体情况,但似乎技术含量低,而且可能也不太正确。
我有一种强烈的感觉,我遗漏了一些相当明显的东西。
干杯。
std::wstring_convert
和 std::codecvt...
类 在 C++17 及更高版本中已弃用。不再有在各种字符串 类.
之间进行转换的标准方法
如果你的编译器仍然支持类,你当然可以使用它们。但是,您不能使用它们将 直接 从 std::u16string
转换为 std::wstring
(反之亦然)。您必须先转换为中间 UTF-8 std::string
,然后再转换,例如:
std::u16string utf16 = ...;
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
std::string utf8 = utf16conv.to_bytes(utf16);
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wconv;
std::wstring wstr = wconv.from_bytes(utf8);
只知道当 类 最终从标准库中删除时,这种方法 将 中断。
使用 std::copy()
(或简单地使用各种 std::wstring
数据 construct/assign 方法)仅适用于 Windows,其中 wchar_t
和 char16_t
都是 16 位大小,表示 UTF-16:
std::u16string utf16 = ...;
std::wstring wstr;
#ifdef _WIN32
wstr.reserve(utf16.size());
std::copy(utf16.begin(), utf16.end(), std::back_inserter(wstr));
/*
or: wstr = std::wstring(utf16.begin(), utf16.end());
or: wstr.assign(utf16.begin(), utf16.end());
or: wstr = std::wstring(reinterpret_cast<const wchar_t*>(utf16.c_str()), utf16.size());
or: wstr.assign(reinterpret_cast<const wchar_t*>(utf16.c_str()), utf16.size());
*/
#else
// do something else ...
#endif
但是,在其他平台上,wchar_t
是表示 UTF-32 的 32 位大小,您需要使用上面显示的代码或 platform-specific 实际转换数据API 或可以进行数据转换的第 3 方 Unicode 库,例如 libiconv
、ICU
。等等
我发现了一堆关于类似主题的问题,但没有关于使用 <codecvt>
进行宽到宽转换的问题,这应该是现代代码中的正确选择。
std::codecvt_utf16<wchar_t>
似乎是执行转换的合乎逻辑的选择。
然而,std::wstring_convert
似乎期望 std::string
一方面。方法 from_bytes
和 to_bytes
强调了这个目的。
我的意思是,到目前为止最好的解决方案是 std::copy
,它可能适用于我的具体情况,但似乎技术含量低,而且可能也不太正确。
我有一种强烈的感觉,我遗漏了一些相当明显的东西。
干杯。
std::wstring_convert
和 std::codecvt...
类 在 C++17 及更高版本中已弃用。不再有在各种字符串 类.
如果你的编译器仍然支持类,你当然可以使用它们。但是,您不能使用它们将 直接 从 std::u16string
转换为 std::wstring
(反之亦然)。您必须先转换为中间 UTF-8 std::string
,然后再转换,例如:
std::u16string utf16 = ...;
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
std::string utf8 = utf16conv.to_bytes(utf16);
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wconv;
std::wstring wstr = wconv.from_bytes(utf8);
只知道当 类 最终从标准库中删除时,这种方法 将 中断。
使用 std::copy()
(或简单地使用各种 std::wstring
数据 construct/assign 方法)仅适用于 Windows,其中 wchar_t
和 char16_t
都是 16 位大小,表示 UTF-16:
std::u16string utf16 = ...;
std::wstring wstr;
#ifdef _WIN32
wstr.reserve(utf16.size());
std::copy(utf16.begin(), utf16.end(), std::back_inserter(wstr));
/*
or: wstr = std::wstring(utf16.begin(), utf16.end());
or: wstr.assign(utf16.begin(), utf16.end());
or: wstr = std::wstring(reinterpret_cast<const wchar_t*>(utf16.c_str()), utf16.size());
or: wstr.assign(reinterpret_cast<const wchar_t*>(utf16.c_str()), utf16.size());
*/
#else
// do something else ...
#endif
但是,在其他平台上,wchar_t
是表示 UTF-32 的 32 位大小,您需要使用上面显示的代码或 platform-specific 实际转换数据API 或可以进行数据转换的第 3 方 Unicode 库,例如 libiconv
、ICU
。等等