如何使用 转换 std::U16string -> std::wstring <codecvt>?

how does one convert std::u16string -> std::wstring using <codecvt>?

本文关键字:std gt codecvt lt wstring 何使用 转换 U16string      更新时间:2024-09-21

我发现了一堆关于类似主题的问题,但没有关于<codecvt>的宽到宽转换的问题,这在现代代码中应该是正确的选择。

std::codecvt_utf16<wchar_t>似乎是执行转换的合乎逻辑的选择。

然而,std::wstring_convert似乎在一端期望std::string。方法from_bytesto_bytes强调了这一目的。

我的意思是,到目前为止最好的解决方案是std::copy,它可能适用于我的特定案例,但似乎技术含量有点低,可能也不太正确。

我有一种紧张的感觉,我错过了一些显而易见的东西。

干杯。

std::wstring_convertstd::codecvt...类在C++17以后的版本中已被弃用。在各种字符串类之间转换不再有标准的方法。

如果您的编译器仍然支持这些类,那么您当然可以使用它们。但是,不能使用它们直接将std::u16string转换为std::wstring(反之亦然(。您必须先转换为中间UTF-8std::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数据构造/分配方法(只能在Windows上工作,其中wchar_tchar16_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的大小为32位,表示UTF-32,您需要使用上面显示的代码或特定于平台的API或可以进行数据转换的第三方Unicode库(如libiconvICU(来实际转换数据。等

您不能使用它们直接从std::u16string转换为std::wstring(反之亦然(。您必须首先转换为中间UTF-8 std::字符串,然后再转换为

情况似乎并非如此clang:将const char16_t*(UTF-16(转换为wstring(UCS-4(显示:

u16string s = u"hello";
wstring_convert<codecvt_utf16<wchar_t, 0x10ffff, little_endian>,
wchar_t> conv;
wstring ws = conv.from_bytes(
reinterpret_cast<const char*> (&s[0]),
reinterpret_cast<const char*> (&s[0] + s.size()));