简体   繁体   English

已弃用的标头<codecvt>替代品

[英]Deprecated header <codecvt> replacement

A bit of foreground: my task required converting UTF-8 XML file to UTF-16 (with proper header, of course).有点前景:我的任务需要将 UTF-8 XML 文件转换为 UTF-16(当然还有适当的标头)。 And so I searched about usual ways of converting UTF-8 to UTF-16, and found out that one should use templates from <codecvt> .因此,我搜索了将 UTF-8 转换为 UTF-16 的常用方法,并发现应该使用<codecvt>模板。

But now when it is deprecated , I wonder what is the new common way of doing the same task?但是现在当它被 弃用时,我想知道完成相同任务的新常见方法是什么?

(Don't mind using Boost at all, but other than that I prefer to stay as close to standard library as possible.) (完全不介意使用 Boost,但除此之外,我更喜欢尽可能接近标准库。)

Don't worry about that.别担心。

According to the same information source :根据同一信息来源

this library component should be retired to Annex D, along side , until a suitable replacement is standardized .这个库组件应该同时退役到附件 D,直到一个合适的替换被标准化

So, you can still use it until a new standardized, more-secure version is done.因此,在新的标准化、更安全的版本完成之前,您仍然可以使用它。

std::codecvt template from <locale> itself isn't deprecated. <locale>本身的std::codecvt模板没有被弃用。 For UTF-8 to UTF-16, there is still std::codecvt<char16_t, char, std::mbstate_t> specialization.对于 UTF-8 到 UTF-16,仍然存在std::codecvt<char16_t, char, std::mbstate_t>

However, since std::wstring_convert and std::wbuffer_convert are deprecated along with the standard conversion facets, there isn't any easy way to convert strings using the facets.但是,由于std::wstring_convertstd::wbuffer_convert与标准转换方面一起被弃用,因此没有任何简单的方法可以使用这些方面来转换字符串。

So, as Bolas already answered: Implement it yourself (or you can use a third party library, as always) or keep using the deprecated API.因此,正如 Bolas 已经回答的那样:自己实现它(或者您可以像往常一样使用第三方库)或继续使用已弃用的 API。

The new way is... you write it yourself.新方法是……你自己写。 Or just rely on deprecated functionality.或者只是依赖已弃用的功能。 Hopefully, the standards committee won't actually remove codecvt until there is a functioning replacement.希望标准委员会不会真正删除codecvt,直到有一个功能性的替代品。

But at present, there isn't one.但目前,没有。

Since nobody really answers the question and provides usable replacement code, here is one but it's only for Windows:由于没有人真正回答这个问题并提供可用的替换代码,这里有一个但仅适用于 Windows:

#include <string>
#include <stdexcept>
#include <Windows.h>

std::wstring string_to_wide_string(const std::string& string)
{
    if (string.empty())
    {
        return L"";
    }

    const auto size_needed = MultiByteToWideChar(CP_UTF8, 0, &string.at(0), (int)string.size(), nullptr, 0);
    if (size_needed <= 0)
    {
        throw std::runtime_error("MultiByteToWideChar() failed: " + std::to_string(size_needed));
    }

    std::wstring result(size_needed, 0);
    MultiByteToWideChar(CP_UTF8, 0, &string.at(0), (int)string.size(), &result.at(0), size_needed);
    return result;
}

std::string wide_string_to_string(const std::wstring& wide_string)
{
    if (wide_string.empty())
    {
        return "";
    }

    const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), nullptr, 0, nullptr, nullptr);
    if (size_needed <= 0)
    {
        throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(size_needed));
    }

    std::string result(size_needed, 0);
    WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), &result.at(0), size_needed, nullptr, nullptr);
    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM