我在一个类似的主题上发现了许多问题,但是没有关于<codecvt>从宽到宽转换的问题,这在现代代码中应该是正确的选择。
std::codecvt_utf16<wchar_t>似乎是执行转换的合乎逻辑的选择。
然而,std::wstring_convert似乎期望std::string在一端。from_bytes和to_bytes方法都强调了这一目的。
我的意思是,到目前为止,最好的解决方案是像std::copy这样的解决方案,它可能适用于我的具体情况,但似乎技术含量较低,而且可能也不太正确。
我有一种感觉,我遗漏了一些很明显的东西。
干杯。
发布于 2022-01-21 17:39:28
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数据构造/赋值方法)只适用于wchar_t,其中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大小为32位,表示UTF-32,则需要实际转换数据,使用上面所示的代码,或者使用特定于平台的API或第三方Unicode库来进行数据转换,例如libiconv、ICU。等。
https://stackoverflow.com/questions/70801246
复制相似问题