【问题标题】:how does one convert std::u16string -> std::wstring using <codecvt>?如何使用 <codecvt> 转换 std::u16string -> std::wstring?
【发布时间】:2022-01-21 12:24:31
【问题描述】:

我发现了一堆关于类似主题的问题,但没有关于使用 &lt;codecvt&gt; 进行宽到宽转换的问题,这应该是现代代码中的正确选择。

std::codecvt_utf16&lt;wchar_t&gt; 似乎是执行转换的合理选择。

但是,std::wstring_convert 似乎希望 std::string 在一端。 from_bytesto_bytes 方法强调了这个目的。

我的意思是,迄今为止最好的解决方案是 std::copy,它可能适用于我的具体情况,但似乎技术含量低,也可能不太正确。

我有一种感觉,我错过了一些相当明显的东西。

干杯。

【问题讨论】:

    标签: c++ string unicode type-conversion


    【解决方案1】:

    从 C++17 开始,std::wstring_convertstd::codecvt... 类已被弃用。不再有在各种字符串类之间进行转换的标准方法。

    如果您的编译器仍然支持这些类,您当然可以使用它们。但是,您不能使用它们直接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 或第 3 方 Unicode 库来实际转换数据可以做数据转换的,如libiconvICU。等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多