CString与LPCWSTR、LPSTR、char*、LPWSTR等类型的转换以及CString和LPCTSTR的关系

Cstring构造函数可以传入
LPCSTR(ANSI字符集时,等价于LPCTSTR),
LPCWSTR(UNICODE字符集时,等价于LPCTSTR),
Char*(ANSI字符集时,等价于LPSTR,LPTSTR),
Wchar_t*(UNICODE字符集时,等价于LPWSTR,LPTSTR),
Unsigned Char*,
Const Unsigned Char*
等参数来构造Cstring对象.

一.CString与LPCWSTR 

   LPCWSTR 是Unicode字符串指针,初始化时串有多大,申请空间就有多大,以后存贮若超过则出现无法预料的结果,这是它与CString的不同之处。

   CString是一个串类,内存空间类会自动管理。

CString转换成LPCWSTR

Cstring str;

方法一:(只适用于UNICODE字符集)

LPWSTR  lpstr = (LPWSTR)(LPCWSTR)str;

方法er(只适用于ANSI字符集)

CString str=_T("TestStr"); 
USES_CONVERSION; 
LPCWSTR lpcwStr = A2CW((LPCSTR)str);

Cstring和LPCTSTR可以通用,在使用ANSI字符集时,LPCTSTR == LPCSTR
A2CW表示(LPCSTR)  -> (LPCWSTR)

USER_CONVERSION表示用来定义一些中间变量,在使用ATL的转换宏之前必须定义该语句。

LPCWSTR转换成CString(通用)

LPCWSTR lpcwStr = L"TestWStr"; 
CString str(lpcwStr);//使用Cstring的构造函数,传入lpcsStr时,构造临时对象

CString转换成LPWSTR(通用)

 LPWSTR lpcwStr = str.AllocSysString();//返回Whart_t*

 

二.CString与LPSTR转换

LPSTR是ANSI字符串指针

CString转换成LPSTR:

方法一:(只使用于ANSI字符集):

CString strFileName;
LPSTR lpStr = (LPSTR)(LPCSTR)strFileName;

方法二(通用):

CString strFileName;
LPSTR lpStr = strFileName.GetBuffer();//ANSI 
或
LPWSTR lpStr = strFileName.GetBuffer();//UICODE
strFileName.ReleaseBuffer();//注意释放Buffer
//GetBuffer返回PXSTR(LPTSTR),不是Const常量,

LPSTR转换成CString:

LPSTR lpStr = _T("TestStr"); //ANSI
CString str(lpStr);//使用Cstring的构造函数,传入lpStr时,构造临时对象

 

三.CString和char*转换

CString转换成char*
方法一(适用于ANSI字符集):

CString str;

char* p = str.GetBuffer();//返回LPTSTR

str.ReleaseBuffer();

不给 GetBuffer 传递参数时,它使用默认值 0,意思是:“给我这个字符串的指针,我保证不加长它”。假设你想增加字符串的长度,就必须将你需要的字符空间大小(注意:Getbuffer字符而不是字节,因为 CString 是以隐含方式感知 Unicode 的)传给它。当调用 ReleaseBuffer 时,字符串的实际长度会被重新计算,然后存入CString 对象中。
在 GetBuffer 和 ReleaseBuffer 之间这个范围,一定不能使用你要操作的这个缓冲的 CString 对象的任何方法。
因为 ReleaseBuffer 被调用之前,该 CString 对象的完整性得不到保障。

LPTSTR p = s.GetBuffer();
// do something with p
int m = s.GetLength(); // 可能出错!!!
s.ReleaseBuffer();
int n = s.GetLength(); // 正确!!!

方法二(适用于ANSI字符集):

CString str;
char* p = (LPSTR)(LPCSTR)str;

 

char*转换成CString

 char* p = "test";
 CString str = ("%s",p);//或 Cstring str(p);

 
四.CString和LPCTSTR互换
ANSI模式下,const char* 等价于LPCTSTR,即转换Cstring到const Char*即可.
UNICODE模式下,const wchar_t*等价于LPCTSTR,即转换Cstring到Const Char*即可.
CString 转LPCTSTR
C++编译器自动调用CString重载的操作符 LPCTSTR()来进行 隐式的类型转换
 
CString cStr;
const char *lpctStr 或 const wchar_t * lpctstr=(LPCTSTR)cStr;

LPCTSTR转CString
C++编译器则自动调用CString的构造函数来构造临时的CString对象
LPCTSTR lpctStr;
CString cStr=lpctStr;//Cstring cStr(lpctStr);

 

转载内容:

五.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中适用于ANSI的代码已经不成立。

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等宏基本上不需要啦

 

CString和LPCTSTR的关系

类型理解
  LPCTSTR类型:
  L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32位操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。
  P表示这是一个指针
  C表示是一个常量
  T表示在Win32环境中, 有一个_T宏
  STR表示这个变量是一个字符串
详细释义
      这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。
  所以LPCTSTR就表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串。
  在程序中我们大部分时间要使用带T的类型定义。
  LPCTSTR == Const TCHAR *
   CString 和 LPCTSTR 可以说通用。 原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。
  常量字符串ansi和unicode的区分是由宏_T来决定的。但是用_T("abcd")时, 字符串"abcd"就会根据编译时的是否定一_UNICODE来决定是char* 还是 w_char*。 同样,TCHAR 也是相同目的字符宏。 看看定义就明白了。
  简单起见,下面只介绍 ansi 的情况,unicode 可以类推。
  ANSI字符集时,LPCTSTR 就是 const char*, 是常量字符串(不能修改的)。
  而LPTSTR 就是 char*, 即普通字符串(非常量,可修改的)。
        UNICODE字符集时, LPCTSTR 就是 const wchar_t*, 是常量字符串(不能修改的)。
  而LPTSTR 就是 wchar_t*, 即普通字符串(非常量,可修改的)。
  这两种都是基本类型, 而CString 是 C++类, 兼容这两种基本类型是最起码的任务了。
  由于const char* 最简单(常量,不涉及内存变更,操作迅速), CString 直接定义了一个类型转换函数:
  operator LPCTSTR( )
  {.
  .....
  }
  函数直接返回所维护的字符串。
  当你需要一个const char* 而传入了CString时, C++编译器自动调用 CString重载的操作符 LPCTSTR()来进行 隐式的类型转换。
  当需要CString , 而传入了 const char* 时(其实 char* 也可以),C++编译器则自动调用CString的构造函数来构造临时的 CString对象。
   因此CString 和 LPCTSTR 基本可以通用。
  但是 LPTSTR又不同了,它是 char*, 意味着你随时可能修改里面的数据,这就需要内存管理了(如字符串变长,原来的存贮空间就不够了,则需要重新调整分配内存)。
  所以 不能随便的将 const char* 强制转换成 char* 使用。
  例如:
  LPSTR lpstr = (LPSTR)(LPCTSTR)string;  就是这种不安全的使用方法。
  这个地方使用的是强制类型转换,你都强制转换了,C++编译器当然不会拒绝你,但同时他也认为你确实知道自己要做的是什么。因此是不会给出警告的。
  强制的任意类型转换是C(++)的一项强大之处,但也是一大弊端。这一问题在 vc6 以后的版本(仅针对vc而言)中得到逐步的改进(你需要更明确的类型转换声明)。
  其实在很多地方都可以看到类似 LPSTR lpstr = (LPSTR)(LPCTSTR)string; 的用法,这种情况一般是函数的约束定义不够完善的原因, 比如一个函数接受一个字符串参数的输入,里面对该字符串又没有任何的修改,那么该参数就应该定义成 const char*, 但是很多初学者弄不清const地用法,或者是懒, 总之就是随意写成了 char* 。 这样子传入CString时就需要强制的转换一下。
  这种做法是不安全的,也是不被建议的用法,你必须完全明白、确认该字符串没有被修改。
   CString 转换到 LPTSTR (char*), 预定的做法是调用CString的GetBuffer函数,使用完毕之后一般都要再调用ReleaseBuffer函数来确认修改 (某些情况下也有不调用ReleaseBuffer的,同样你需要非常明确为什么这么做时才能这样子处理,一般应用环境可以不考虑这种情况)。
  同时需要注意的是, 在GetBuffer 和 ReleaseBuffer之间,CString分配了内存交由你来处理,因此不能再调用其他的CString函数。
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值