废弃的头部 < codecvt > 替换

一点前景: 我的任务需要将 UTF-8 XML 文件转换为 UTF-16(当然,要有适当的头)。因此,我搜索了将 UTF-8转换为 UTF-16的常用方法,发现应该使用来自 <codecvt>的模板。

但是现在当它是 不赞成时,我想知道做同样的任务的新的常用方法是什么?

(完全不介意使用 Boost,但除此之外,我更喜欢尽可能接近标准库。)

29080 次浏览

std::codecvt template from <locale> itself isn't deprecated. For UTF-8 to UTF-16, there is still std::codecvt<char16_t, char, std::mbstate_t> specialization.

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.

So, as Bolas already answered: Implement it yourself (or you can use a third party library, as always) or keep using the deprecated 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.

But at present, there isn't one.

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.

So, you can still use it until a new standardized, more-secure version is done.

Since nobody really answers the question and provides usable replacement code, here is one but it's only for 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;
}