http://blog.csdn.net/zhouxuguang236/article/details/8761497
在Windows编程中,经常会碰到字符串之间的转换,char*转LPCWSTR也是其中一个比较常见的转换。下面就列出几种比较常用的转换方法。
1、通过MultiByteToWideChar函数转换
MultiByteToWideChar函数是将多字节转换为宽字节的一个API函数,它的原型如下:
[cpp] view plain copy
- int MultiByteToWideChar(
- UINT CodePage, // code page
- DWORD dwFlags, // character-type options
- LPCSTR lpMultiByteStr, // string to map
- int cbMultiByte, // number of bytes in string
- LPWSTR lpWideCharStr, // wide-character buffer
- int cchWideChar // size of buffer
- );
LPCWSTR实际上也是CONST WCHAR *类型
[cpp] view plain copy
- char* szStr = "测试字符串";
- WCHAR wszClassName[256];
- memset(wszClassName,0,sizeof(wszClassName));
- MultiByteToWideChar(CP_ACP,0,szStr,strlen(szStr)+1,wszClassName,
- sizeof(wszClassName)/sizeof(wszClassName[0]));
2、通过T2W转换宏
[cpp] view plain copy
- char* szStr = "测试字符串";
- CString str = CString(szStr);
- USES_CONVERSION;
- LPCWSTR wszClassName = new WCHAR[str.GetLength()+1];
- wcscpy((LPTSTR)wszClassName,T2W((LPTSTR)str.GetBuffer(NULL)));
- str.ReleaseBuffer();
3、通过A2CW转换
[cpp] view plain copy
- char* szStr = "测试字符串";
- CString str = CString(szStr);
- USES_CONVERSION;
- LPCWSTR wszClassName = A2CW(W2A(str));
- str.ReleaseBuffer();
上述方法都是UniCode环境下测试的。
http://www.aichengxu.com/other/65827.htm
char :单字节变量类型,表示ASCII码。
wchar_t :宽字节变量类型,用于表示Unicode字符。在<string.h>定义为:typedef unsigned short wchar_t。
TCHAR: VS下的中间类型。在“使用Unicode字符集”下TCHAR定义为wchar_t,在字符集 “未设置” 条件下TCHAR定义为char。
A2T,及T2A是两个非常有用的宏,可以用于实现char*和wchar_t*字符串之间的转换。宏的实现也将会在测试代码中给出,不感兴趣的直接跳过。费话不多说,直接上测试代码,参考代码注释。
// demo1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <cstring>
using namespace std;
#include <atlbase.h>
#include <Windows.h>
void test_L_macro()
{
char astr[] = "hello";
cout<<"sizeof(astr):"<<sizeof(astr)<<endl
<<"strlen(astr):"<<strlen(astr)<<endl;
//L"str"表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。
wchar_t wstr[] = L"hello"; //typedef unsigned short wchar_t
cout<<"sizeof(wstr)"<<sizeof(wstr)<<endl
<<"wcslen(wstr):"<<wcslen(wstr)<<endl;
}
void test_T_macro()
{
/*
#ifdef _UNICODE
#define __T(x) L ## x
#else
#define __T(x) x
#endif
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
#define TEXT(quote) __TEXT(quote)
#ifdef _UNICODE
typedef char TCHAR;
#else
typede wchar_t TCHAR;
#endif
*/
//如果在程序中使用了TCHAR,那么就不应该使用ANSI的strXXX函数或者Unicode的wcsXXX函数了,
//而必须使用tchar.h中定义的_tcsXXX函数。
TCHAR buf[] = _T("hello");
cout<<"sizeof(buf):"<<sizeof(buf)<<endl
<<"_tcslen(lpBuf):"<<_tcslen(buf)<<endl;
/*
#ifdef _UNICODE
typedef wchar_t WCHAR;// wc, 16-bit UNICODE character
typedef __nullterminated WCHAR *LPWSTR;
typedef LPWSTR PTSTR, LPTSTR;
#else
typedef char CHAR;
typedef __nullterminated CHAR *LPSTR;
typedef LPSTR LPTSTR;
#endif
*/
LPTSTR lpBuf = TEXT("hello");
cout<<"_tcslen(lpBuf):"<<_tcslen(lpBuf)<<endl;
}
void test_A2T()
{
USES_CONVERSION;
char *astr = "hello";
LPTSTR wstr = A2T(astr);
#ifdef _UNICODE
wcout<<"wcout\<\<wstr:"<<wstr<<endl;
#else
cout<<"cout\<\<wstr:"<<wstr<<endl;
#endif
}
void test_A2T_()
{
int _convert = 0;
(_convert);
UINT _acp = ATL::_AtlGetConversionACP() ;
(_acp);
LPCWSTR _lpw = 0;
(_lpw);
LPCSTR _lpa = 0;
(_lpa);
char *astr = "hello";
LPTSTR wstr = ( ((_lpa = astr) == 0) ? 0 : ( _convert = (lstrlenA(_lpa)+1), (2147483647/2<_convert)? 0 : AtlA2WHelper((LPWSTR) _alloca(_convert*sizeof(WCHAR)), _lpa, _convert, _acp)));
//p.s. AtlA2WHelper调用了函数MultiByteToWideChar
//_alloca函数用于在栈上分配内存,参考:http://msdn.microsoft.com/en-us/library/wb1s57t5.aspx
wcout<<"wcout\<\<wstr:"<<wstr<<endl;
}
void test_T2A()
{
USES_CONVERSION;
LPTSTR wstr = _T("hello");
char *astr = T2A(wstr);
cout<<"cout\<\<astr:"<<astr<<endl;
}
void test_T2A_()
{
int _convert = 0;
(_convert);
UINT _acp = ATL::_AtlGetConversionACP() ;
(_acp);
LPCWSTR _lpw = 0;
(_lpw);
LPCSTR _lpa = 0;
(_lpa);
LPTSTR wstr = L"hello";
char *astr = ( ((_lpw = wstr) == 0) ? 0 : ( (_convert = (lstrlenW(_lpw)+1), (_convert>2147483647/2) ? 0 : AtlW2AHelper((LPSTR) _alloca(_convert*sizeof(WCHAR)), _lpw, _convert*sizeof(WCHAR), _acp))));
//p.s. AtlW2AHelper调用了函数WideCharToMultiByte
//_alloca函数用于在栈上分配内存,参考:http://msdn.microsoft.com/en-us/library/wb1s57t5.aspx
cout<<"cout\<\<astr:"<<astr<<endl;
}
int main()
{
test_L_macro();
test_T_macro();
test_A2T();
test_A2T_();
test_T2A();
test_T2A_();
}
CString与LPCWSTR、LPSTR、char*、LPWSTR等类型的转换
一.CString与LPCWSTR
两者的不同:LPCWSTR 是Unicode字符串指针,初始化时串有多大,申请空间就有多大,以后存贮若超过则出现无法预料的结果,这是它与CString的不同之处。而CString是一个串类,内存空间类会自动管理。
CString转换成LPCWSTR
方法一:CString strFileName;
LPCWSTR lpcwStr = strFileName.AllocSysString();
方法二:CString str=_T("TestStr");
USES_CONVERSION;
LPCWSTR lpcwStr = A2CW((LPCSTR)str);
MFC中CString和LPSTR是可以通用,其中A2CW表示(LPCSTR) -> (LPCWSTR),USER_CONVERSION表示用来定义一些中间变量,在使用ATL的转换宏之前必须定义该语句。
LPCWSTR转换成CString
LPCWSTR lpcwStr = L"TestWStr";
CString str(lpcwStr);
CString str;
LPWSTR lpstr = (LPWSTR)(LPCWSTR)str;
二.CString与LPSTR转换
CString转换成LPSTR:
方法一:CString strFileName;
LPSTR lpStr = strFileName.GetBuffer();
strFileName.ReleaseBuffer();
方法二:CString strFileName;
LPSTR lpStr = (LPSTR)(LPCSTR)strFimeName;
LPSTR转换成CString:
LPSTR lpStr = L"TestStr";
CString str(lpStr);
注意:CString和LPCSTR可直接转换,如下:
CString str;
LPCSTR lpcStr = (LPCSTR)str;
三.CString和char*转换
CString转换成char*
方法一:CString str;
char* p = str.GetBuffer();
方法二:CString str;
char* p = (LPSTR)(LPCSTR)str;
char*转换成CString
char* p = "test";
CString str = ("%s",p);
四.String和int、float的转换
可以使用atoi,atof,atol等函数来完成。
五.LPSTR(char*)和LPWSTR的转换
可以使用下面的ATL宏来进行,最好是将变量定义成TCHAR、LPTSTR等T类型,可以避免转换。
ATL宏介绍:
A2BSTR OLE2A T2A W2A
A2COLE OLE2BSTR T2BSTR W2BSTR
A2CT OLE2CA T2CA W2CA
A2CW OLE2CT T2COLE W2COLE
A2OLE OLE2CW T2CW W2CT
A2T OLE2T T2OLE W2OLE
A2W OLE2W T2W W2T
A :ANSI 字符串,也就是 MBCS。
W、OLE 宽字符串,也就是 UNICODE。
T 中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A
C const 的缩写
利用这些宏,可以快速的进行各种字符间的转换。使用前必须包含头文件,并且申明USER_CONVERSION;使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:
1、只适合于进行短字符串的转换;
2、不要试图在一个次数比较多的循环体内进行转换;
3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;
4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();
void Func1(LPSTR lpStr);
void Func2(LPWSTR lpwStr);
TCHAR name[256];
TCHAR* pName = new TCHAR[256];
Func1(name); // Func1(pName);
Func2(name); // Func2(pName);
注意在VS2005中上面用红色标记的代码已经不成立。
VS2005中CString已经改为宽字符型,一些转换如下:
char name[10];
TCHAR sex[5] ;
char *p = name;
TCHAR *pw = sex;
LPSTR lpstr = name;
LPCSTR lpcstr = name;
lpcstr = lpstr;
lpstr = p;
p = (char*)sex;
pw = (WCHAR*)name;
LPWSTR lpwstr = (LPWSTR)lpstr;
lpwstr = (LPWSTR)lpcstr;
LPCWSTR lpcwstr = (LPCWSTR)lpstr;
lpcwstr = (LPCWSTR)name;
CString str(lpstr);
CString str1(lpcstr);
CString str2(lpwstr);
CString str3(lpcwstr);
CString str4(name);
CString str5(sex);
lpwstr = (LPWSTR)(LPCWSTR)str;
lpstr = (LPSTR)(LPCWSTR)str;
lpcstr = (LPCSTR)(LPCWSTR)str;
p = (char*)str.GetBuffer();
pw = str.GetBuffer();
可以看出转换更加简单了,基本上可以直接转换,A2W等宏基本上不需要啦