随着VS2003升级到VS2005,很多以前熟悉的输入输出方式以及参数传递方式都不再有效
(参看 vs2003 到vs2005代码升级要点http://bianyongtao.spaces.live.com/blog/cns!DD6CD3607CCE4603!214.entry )。
其中根字符串相关的内容是,wcout不再有效,默认参数传递方式由char*改成了wchar_t*等几个方面。为了解决上面的这些问题,
这篇文章里,将给出几种C++ std::string和std::wstring相互转换的转换方法。
第一种方法:调用WideCharToMultiByte()和MultiByteToWideChar(),代码如下(关于详细的解释,可以参考《windows核心编程》):
1 #include <string> 2 #include <windows.h> 3 using namespace std; 4 //Converting a WChar string to a Ansi string 5 std::string WChar2Ansi(LPCWSTR pwszSrc) 6 { 7 int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL); 8 if (nLen <= 0) 9 return std::string(""); 10 char* pszDst = new char[nLen]; 11 if (NULL == pszDst) 12 return std::string(""); 13 WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL); 14 pszDst[nLen - 1] = 0; 15 std::string strTemp(pszDst); 16 delete[] pszDst; 17 return strTemp; 18 } 19 string ws2s(wstring& inputws) 20 { 21 return WChar2Ansi(inputws.c_str()); 22 } 23 //Converting a Ansi string to WChar string 24 std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen) 25 { 26 int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0); 27 if (nSize <= 0) return NULL; 28 WCHAR *pwszDst = new WCHAR[nSize + 1]; 29 if (NULL == pwszDst) 30 return NULL; 31 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, pwszDst, nSize); 32 pwszDst[nSize] = 0; 33 if (pwszDst[0] == 0xFEFF) // skip Oxfeff 34 for (int i = 0; i < nSize; i++) 35 pwszDst[i] = pwszDst[i + 1]; 36 wstring wcharString(pwszDst); 37 delete pwszDst; 38 return wcharString; 39 } 40 41 std::wstring s2ws(const string& s) 42 { 43 return Ansi2WChar(s.c_str(), s.size()); 44 }
第二种方法:采用ATL封装_bstr_t的过渡:(注,_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过,无移植性);
1 #include <string> 2 #include <comutil.h> 3 using namespace std; 4 #pragma comment(lib, "comsuppw.lib") 5 string ws2s(const wstring& ws); 6 wstring s2ws(const string& s); 7 string ws2s(const wstring& ws) 8 { 9 _bstr_t t = ws.c_str(); 10 char* pchar = (char*)t; 11 string result = pchar; 12 return result; 13 } 14 wstring s2ws(const string& s) 15 { 16 _bstr_t t = s.c_str(); 17 wchar_t* pwchar = (wchar_t*)t; 18 wstring result = pwchar; 19 return result; 20 }
第三种方法:使用CRT库的mbstowcs()函数和wcstombs()函数,平台无关,需设定locale。
1 #include <string> 2 #include <locale.h> 3 using namespace std; 4 string ws2s(const wstring& ws) 5 { 6 string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C"; 7 setlocale(LC_ALL, "chs"); 8 const wchar_t* _Source = ws.c_str(); 9 size_t _Dsize = 2 * ws.size() + 1; 10 char *_Dest = new char[_Dsize]; 11 memset(_Dest, 0, _Dsize); 12 wcstombs(_Dest, _Source, _Dsize); 13 string result = _Dest; 14 delete[]_Dest; 15 setlocale(LC_ALL, curLocale.c_str()); 16 return result; 17 } 18 wstring s2ws(const string& s) 19 { 20 setlocale(LC_ALL, "chs"); 21 const char* _Source = s.c_str(); 22 size_t _Dsize = s.size() + 1; 23 wchar_t *_Dest = new wchar_t[_Dsize]; 24 wmemset(_Dest, 0, _Dsize); 25 mbstowcs(_Dest, _Source, _Dsize); 26 wstring result = _Dest; 27 delete[]_Dest; 28 setlocale(LC_ALL, "C"); 29 return result; 30 }
===================================================
ps:
以上是我在开发一个小程序碰到的问题时找到的文章,由于对于在c++里string 和wstring的转换,开始我的理解只是单双字节的问题,后来发现这个和local是相关的。
以上是我在开发一个小程序碰到的问题时找到的文章,由于对于在c++里string 和wstring的转换,开始我的理解只是单双字节的问题,后来发现这个和local是相关的。