bright 的个人资料Bright Moment照片日志列表 工具 帮助

日志


1月7日

VS2005:C++ std::string, std::wstring转换方法(转载)

引用自: >>VS2005:C++ std::string, std::wstring转换方法<<
    随着VS2003升级到VS2005,很多以前熟悉的`输入输出方式以及参数传递方式都不再有效(参看 vs2003 到vs2005代码升级要点)。其中根字符串相关的内容是,wcout不再有效,默认参数传递方式由char*改成了wchar_t*等几个方面。为了解决上面的这些问题,这篇文章里,我将给出几种C++ std::string和std::wstring相互转换的转换方法。
第一种方法:调用WideCharToMultiByte()和MultiByteToWideChar(),代码如下(关于详细的解释,可以参考《windows核心编程》):
#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());}
第二种方法:采用ATL封装_bstr_t的过渡:(注,_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过,无移植性);
#include <string>
#include <comutil.h>
using namespace std;
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;
}
特别要指出的一点是,为了使用_bstr_t, 除了添加<comutil.h>头文件外,还需要在工程里面加入一个库文件comsuppw.lib。请在工程属性->link->command Line处添加。
第三种方法:使用CRT库的mbstowcs()函数和wcstombs()函数,平台无关,需设定locale。
#include <string>
#include <locale.h>
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#类库:(待续
其中第四种,我的实现始终存在一些问题。 第五种,我只是知道有这么一种方案,没有时间去详细了解,算是给一些提示吧。

评论 (4)

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。

若要添加评论,请使用您的 Windows Live ID 登录(如果您使用过 Hotmail、Messenger 或 Xbox LIVE,您就拥有 Windows Live ID)。登录


还没有 Windows Live ID 吗?请注册

LuoYi发表:
通过搜索引擎找到这篇文章,不错!

希望有纯C++的,平台无关的实现。

另外,VS2005下还是有wcout啊,默认的cout还是ANSI字串的,奇怪。。。
4 月 8 日
libright发表:
应该有出处啊,我是从你那边采用引用的方式弄过来的。
2 月 9 日
byte发表:
转载请注明出处,hiahia
2 月 9 日
不错,我前几天也在unicode中挣扎。
1 月 22 日

引用通告

此日志的引用通告 URL 是:
http://bright-li.spaces.live.com/blog/cns!64A26545E8622B86!332.trak
引用此项的网络日志