1 std::stringstd::wstring相互转换

1.1 windows上的std::string与std::wstring相互转换

在Windows上,可以使用MultiByteToWideChar和WideCharToMultiByte函数来进行std::string和std::wstring之间的转换,代码如下

std::wstring StringToWString(const std::string& str)
{
    int wide_str_size = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
    std::wstring wide_str(wide_str_size, 0);
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &wide_str[0], wide_str_size);

    return wide_str;
}

std::string WStringToString(const std::wstring& wstr)
{
    int narrow_str_size = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
    std::string narrowStr2(narrow_str_size, 0);
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &narrowStr2[0], narrow_str_size, NULL, NULL);

    return narrowStr2;
}

1.2 linux上的std::string与std::wstring相互转换

在Linux上,可以使用mbstowcs和wcstombs函数来进行std::string和std::wstring之间的转换,代码如下

#include <cstring>

std::wstring StringToWString(const std::string& str)
{
    std::wstring wide_str;
    wide_str.resize(mbstowcs(nullptr, str.c_str(), 0) + 1);
    mbstowcs(&wide_str[0], str.c_str(), str.size());
    return wide_str;
}

std::string WStringToString(const std::wstring& wstr)
{
    std::string narrow_str;
    narrow_str.resize(wcstombs(nullptr, wstr.c_str(), 0) + 1);
    wcstombs(&narrow_str[0], wstr.c_str(), wstr.size());
    return narrow_str;
}

1.3 使用示例

我们可以将上述在windows和linux上的实现进行整合,形成一个跨平台的std::string与std::wstring相互转换函数,代码如下

#include <iostream>
#include <string>

#if defined(WIN32) || defined(_WIN32) || defined(_WIN32_) || defined(WIN64) || defined(_WIN64) || defined(_WIN64_)

#include <Windows.h>

std::wstring StringToWString(const std::string& str)
{
    int wide_str_size = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
    std::wstring wide_str(wide_str_size, 0);
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &wide_str[0], wide_str_size);

    return wide_str;
}

std::string WStringToString(const std::wstring& wstr)
{
    int narrow_str_size = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
    std::string narrowStr2(narrow_str_size, 0);
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &narrowStr2[0], narrow_str_size, NULL, NULL);

    return narrowStr2;
}

#elif defined(__linux__)

#include <cstring>

std::wstring StringToWString(const std::string& str)
{
    std::wstring wide_str;
    wide_str.resize(mbstowcs(nullptr, str.c_str(), 0) + 1);
    mbstowcs(&wide_str[0], str.c_str(), str.size());
    return wide_str;
}

std::string WStringToString(const std::wstring& wstr)
{
    std::string narrow_str;
    narrow_str.resize(wcstombs(nullptr, wstr.c_str(), 0) + 1);
    wcstombs(&narrow_str[0], wstr.c_str(), wstr.size());
    return narrow_str;
}

#endif


int main() {
    // std::string 转换为 std::wstring
    std::string narrow_str = "Hello, world!";
    std::wstring wide_str = StringToWString(narrow_str);

    // std::wstring 转换为 std::string
    std::wstring wide_str2 = L"Hello, 世界!";
    std::string narrow_str2 = WStringToString(wide_str2);

    // 输出结果
    std::wcout << wide_str << std::endl;
    std::cout << narrow_str2 << std::endl;

    return 0;
}

1.4 使用std::codecvt_utf8进行std::string与std::wstring相互转换

我们也可以使用std::codecvt_utf8进行std::string与std::wstring相互转换,代码如下

#include <iostream>
#include <string>
#include <locale>
#include <codecvt>

int main() {
    // std::string 转换为 std::wstring
    std::string narrowStr = "Hello, world!";
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    std::wstring wideStr = converter.from_bytes(narrowStr);

    // std::wstring 转换为 std::string
    std::wstring wideStr2 = L"Hello, 世界!";
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter2;
    std::string narrowStr2 = converter2.to_bytes(wideStr2);

    // 输出结果
    std::wcout << wideStr << std::endl;
    std::cout << narrowStr2 << std::endl;

    return 0;
}