在std::string和std::wstring之间转换的多平台方式

Multiplatform way to convert between std::string and std::wstring

本文关键字:std 方式 转换 平台 wstring string 之间      更新时间:2023-10-16

我当前正在使用Windows API的方法MultiByteToWideCharWideCharToMultiBytestd::stringstd::wstring之间进行转换。

我正在"多平台化"我的代码,删除Windows依赖项,所以我想知道上面方法的替代方案。具体来说,使用boost将非常棒。我可以使用哪些方法?这是我目前使用的代码:

const std::wstring Use::stow(const std::string& str)
{
    if (str.empty()) return L"";
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
    std::wstring wstrTo( size_needed, 0 );
    MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
    return wstrTo;
}
const std::string Use::wtos(const std::wstring& wstr)
{
    if (wstr.empty()) return "";
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo( size_needed, 0 );
    WideCharToMultiByte                  (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}

基本上,使用<cstdlib>,您可以获得与Joachim Pileborg所提到的类似的实现。只要您已经将区域设置为您想要的任何位置(例如:setlocale( LC_ALL, "en_US.utf8" );

MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0)=>mbstowcs(nullptr, data(str), size(str))

MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed)=>mbstowcs(data(wstrTo), data(str), size(str))

WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL)=>wcstombs(nullptr, data(wstr), size(wstr))

WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL)=>wcstombs(data(strTo), data(wstr), size(wstr))

编辑:

c++11要求字符串连续分配,如果您正在跨平台编译,这可能很重要,因为以前的标准要求string连续分配。以前调用&str[0]&strTo[0]&wstr[0]&wstrTo[0]可能会导致问题
由于c++17现在是公认的标准,我改进了我建议的替换,使用data,而不是取消对字符串前面的引用。

从您的代码来看,您似乎正在使用utf-8编码。要使用utf-8,请查看UTF8-CPPhttp://utfcpp.sourceforge.net/它是一个只有标题的库

看看utf8to32函数。(请注意,在Windows上,wchar_t是16位,在其他平台(如linux)上,它通常是32位)

const std::wstring Use::stow(const std::string &s)
{
    return std::wstring(s.begin(), s.end());
}
const std::string Use::wtos(const std::wstring &ws)
{
    return std::string(ws.begin(), ws.end());
}