[转]char* CString LPCWSTR等类型转换解决方案

http://blog.csdn.net/zhouxuguang236/article/details/8761497

在Windows编程中,经常会碰到字符串之间的转换,char*转LPCWSTR也是其中一个比较常见的转换。下面就列出几种比较常用的转换方法。

1、通过MultiByteToWideChar函数转换

    MultiByteToWideChar函数是将多字节转换为宽字节的一个API函数,它的原型如下:

[cpp] view plain copy

  1. int MultiByteToWideChar(  
  2.   UINT CodePage,         // code page  
  3.   DWORD dwFlags,         // character-type options  
  4.   LPCSTR lpMultiByteStr, // string to map  
  5.   int cbMultiByte,       // number of bytes in string  
  6.   LPWSTR lpWideCharStr,  // wide-character buffer  
  7.   int cchWideChar        // size of buffer  
  8. );  

LPCWSTR实际上也是CONST WCHAR *类型

[cpp] view plain copy

  1. char* szStr = "测试字符串";  
  2. WCHAR wszClassName[256];  
  3. memset(wszClassName,0,sizeof(wszClassName));  
  4. MultiByteToWideChar(CP_ACP,0,szStr,strlen(szStr)+1,wszClassName,  
  5.     sizeof(wszClassName)/sizeof(wszClassName[0]));  


2、通过T2W转换宏

[cpp] view plain copy

  1. char* szStr = "测试字符串";     
  2. CString str = CString(szStr);  
  3. USES_CONVERSION;  
  4. LPCWSTR wszClassName = new WCHAR[str.GetLength()+1];  
  5. wcscpy((LPTSTR)wszClassName,T2W((LPTSTR)str.GetBuffer(NULL)));  
  6. str.ReleaseBuffer();  


 

3、通过A2CW转换

[cpp] view plain copy

  1. char* szStr = "测试字符串";     
  2. CString str = CString(szStr);  
  3. USES_CONVERSION;  
  4. LPCWSTR wszClassName = A2CW(W2A(str));  
  5. 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等宏基本上不需要啦

猜你喜欢

转载自blog.csdn.net/xian_wwq/article/details/66973681