在c++开发时有的库函数必须传递wstring宽字符串作为参数,在代码中通过L"wstring"定义宽字符串传递参数这没什么难度,问题是实际过程中需要接收输入string数据,这时候就需要将string转换为wstring。经查阅相关资料,string与wstring互相转换有以下几种:
windows系统提供的MultiByteToWideChar和WideCharToMultiByte函数,可以很方便进行类型转换。
#include
#include
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操作系统,如果程序需要跨平台运行这不是好的选择。
这种方法可以实现跨平台string与wstring互相转换,但是仅限c++11/c++14标准,c++17已经弃用。
#include
#include
#include
// convert string to wstring
std::wstring to_wide_string(const std::string &input)
{
std::wstring_convert> converter;
return converter.from_bytes(input);
}
// convert wstring to string
std::string to_byte_string(const std::wstring &input)
{
// std::wstring_convert> converter;
std::wstring_convert> 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;
| ^~~~~~~~~~~~~~~
该方法经测试可以在windows、linux、macos平台编译使用。
#include
#include
#include
#include // 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;
}