c++ 如何使用转换std::u16 string->std::wstring< codecvt>?

wgmfuz8q  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(465)

我发现了一堆关于类似主题的问题,但没有任何关于使用<codecvt>进行宽到宽转换的问题,这应该是现代代码中的正确选择。
std::codecvt_utf16<wchar_t>似乎是执行转换的合理选择。
然而std::wstring_convert似乎在一端期望std::string,方法from_bytesto_bytes强调了这一目的。
我的意思是,到目前为止最好的解决方案是类似std::copy的东西,它可能适用于我的特定情况,但似乎有点低技术,可能也不太正确。
我有一种强烈的感觉,我错过了一些相当明显的东西。
干杯。

ajsxfq5m

ajsxfq5m1#

std::wstring_convertstd::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数据构造/赋值方法)只能在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等。

qmelpv7a

qmelpv7a2#

不能使用它们直接从std::u16 string转换为std::wstring(反之亦然)。必须先转换为中间UTF-8 std::string,然后再转换
clang: converting const char16_t* (UTF-16) to 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()));

相关问题