C++string与wstring类型转换

在c++开发时有的库函数必须传递wstring宽字符串作为参数,在代码中通过L"wstring"定义宽字符串传递参数这没什么难度,问题是实际过程中需要接收输入string数据,这时候就需要将string转换为wstring。经查阅相关资料,string与wstring互相转换有以下几种:

一、windows系统

windows系统提供的MultiByteToWideChar和WideCharToMultiByte函数,可以很方便进行类型转换。

#include <string>
#include <windows.h>
using namespace std;

// Converting a WChar string to a Ansi string
std::string WChar2Ansi(LPCWSTR pwszSrc)
{
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
    if (nLen <= 0)
        return std::string("");
    char *pszDst = new char[nLen];
    if (NULL == pszDst)
        return std::string("");
    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
    pszDst[nLen - 1] = 0;
    std::string strTemp(pszDst);
    delete[] pszDst;
    return strTemp;
}
string ws2s(wstring &inputws)
{
    return WChar2Ansi(inputws.c_str());
}

// Converting a Ansi string to WChar string
std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
{
    int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
    if (nSize <= 0)
        return NULL;
    WCHAR *pwszDst = new WCHAR[nSize + 1];
    if (NULL == pwszDst)
        return NULL;
    MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, pwszDst, nSize);
    pwszDst[nSize] = 0;
    if (pwszDst[0] == 0xFEFF) // skip Oxfeff
        for (int i = 0; i < nSize; i++)
            pwszDst[i] = pwszDst[i + 1];
    wstring wcharString(pwszDst);
    delete pwszDst;
    return wcharString;
}
std::wstring s2ws(const string &s)
{
    return Ansi2WChar(s.c_str(), s.size());
}

int main()
{
    wstring ws = s2ws("E:/DevProject/NodejsProject");
    wstring wsa = L"test wstring";
    printf("%s-%ls\n", "result", wsa.c_str());
    printf("%s-%ls\n", "result", ws.c_str());
}

这种方法局限于windows操作系统,如果程序需要跨平台运行这不是好的选择。

二、c++11/14codecvt库wstring_convert方法

这种方法可以实现跨平台string与wstring互相转换,但是仅限c++11/c++14标准,c++17已经弃用。

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

// convert string to wstring
std::wstring to_wide_string(const std::string &input)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(input);
}
// convert wstring to string
std::string to_byte_string(const std::wstring &input)
{
    // std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.to_bytes(input);
}

当使用非c++11/c++14标准的g++编译时,将会报错:

 error: ‘wstring_convert’ was not declared in this scope
   65 |     wstring_convert<codecvt_utf8<wchar_t>> converter;
      |     ^~~~~~~~~~~~~~~

三、跨平台string与wstring互转最佳选择

该方法经测试可以在windows、linux、macos平台编译使用。

#include <iostream>
#include <string>
#include <cstring>
#include <codecvt> // macos必须,否则提示String2WString函数报错
using namespace std;

// wstring=>string
std::string WString2String(const std::wstring &ws)
{
    std::string strLocale = setlocale(LC_ALL, "");
    const wchar_t *wchSrc = ws.c_str();
    size_t nDestSize = wcstombs(NULL, wchSrc, 0) + 1;
    char *chDest = new char[nDestSize];
    memset(chDest, 0, nDestSize);
    wcstombs(chDest, wchSrc, nDestSize);
    std::string strResult = chDest;
    delete[] chDest;
    setlocale(LC_ALL, strLocale.c_str());
    return strResult;
}

// string => wstring
std::wstring String2WString(const std::string &s)
{
    std::string strLocale = setlocale(LC_ALL, "");
    const char *chSrc = s.c_str();
    size_t nDestSize = mbstowcs(NULL, chSrc, 0) + 1;
    wchar_t *wchDest = new wchar_t[nDestSize];
    wmemset(wchDest, 0, nDestSize);
    mbstowcs(wchDest, chSrc, nDestSize);
    std::wstring wstrResult = wchDest;
    delete[] wchDest;
    setlocale(LC_ALL, strLocale.c_str());
    return wstrResult;
}

int main()
{
    wstring ws = String2WString("E:/DevProject/NodejsProject");
    wstring wsa = L"test wstring";
    printf("%s-%ls\n", "result", wsa.c_str());
    printf("%s-%ls\n", "result", ws.c_str());

    return 0;
}
  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值