Chinaunix首页 | 论坛 | 博客
  • 博客访问: 951634
  • 博文数量: 108
  • 博客积分: 3243
  • 博客等级: 中校
  • 技术积分: 964
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-15 22:09
文章分类

全部博文(108)

文章存档

2020年(2)

2019年(1)

2018年(2)

2017年(9)

2016年(20)

2015年(1)

2013年(1)

2012年(12)

2011年(28)

2010年(27)

2009年(4)

2008年(1)

分类:

2011-05-05 16:16:22

随着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核心编程》):
#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());}

第二种方法:采用ATL封装_bstr_t的过渡:(注,_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过,无移植性);
#include
#include
using namespace std;
#pragma comment(lib, "comsuppw.lib")
string ws2s(const wstring& ws);
wstring s2ws(const string& s);
string ws2s(const wstring& ws)
{
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
wstring s2ws(const string& s)
{
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}
第三种方法:使用CRT库的mbstowcs()函数和wcstombs()函数,平台无关,需设定locale。
#include
#include
using namespace std;
string ws2s(const wstring& ws)
{
string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
string result = _Dest;
delete []_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
wstring s2ws(const string& s)
{
setlocale(LC_ALL, "chs");
const char* _Source = s.c_str();
size_t _Dsize = s.size() + 1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest, 0, _Dsize);
mbstowcs(_Dest,_Source,_Dsize);
wstring result = _Dest;
delete []_Dest;
setlocale(LC_ALL, "C");
return result;
}
//第四种方法,标准C++转换方法:(待续)
//第五种方法,在C++中使用C#类库:(待续
其中第四种,我的实现始终存在一些问题。 第五种,我只是知道有这么一种方案,没有时间去详细了解,算是给一些提示吧。
===================================================
ps:
以上是我在开发一个小程序碰到的问题时找到的文章,由于对于在c++里string 和wstring的转换,开始我的理解只是单双字节的问题,后来发现这个和local是相关的。
现在我的理解是对于unicode,它的形式是双字节,但是要对这些双字节做出正确的解释,是需要正确的page页的,比如:setlocale(LC_ALL, "C"),只是以ansi页来解释,而setlocale(LC_ALL, "chs")是以gbk页码来翻译为中文的双字节。而过程就是mbstowcs,这个单字节转双字节函数。
C++也有处理local的方法,粗略看了看,不感兴趣,总觉得c++ stream 是一个很麻烦的东西,没有c file库的简介(当然stream 加入了对象的高级部分)。而且fstream类有一个大bug,就是不支持unicode的路径,而c file api是支持的。
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/code_pipeline/archive/2007/11/02/1863665.aspx
阅读(5185) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~