首页 > 代码库 > 【编程拾遗】VC++中LPCTSTR、CString、char *、string之间的相互转换

【编程拾遗】VC++中LPCTSTR、CString、char *、string之间的相互转换

字符集

在VC2012中,字符集默认采用Unicode字符集(Use Unicode Charecter Set选项),其值还可以设置为多字节字符集(Use Multi-Byte Charecter Set)。

为什么要使用Unicode

  1. 可以很容易地在不同语言之间进行数据交换。
  2. 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。
  3. 提高应用程序的运行效率。

Windows 2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那么系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序更加有效地运行。
Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。

Windows定义的Unicode数据类型有哪些

WCHAR Unicode字符;
PWSTR 指向Unicode字符串的指针;
PCWSTR 指向一个恒定的Unicode字符串的指针;
对应的ANSI数据类型为CHAR,LPSTR和LPCSTR;
ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。

如何对Unicode进行操作

ANSI 操作函数以str开头 strcpy
Unicode 操作函数以wcs开头 wcscpy
MBCS 操作函数以_mbs开头 _mbscpy
ANSI/Unicode 操作函数以_tcs开头 _tcscpy(C运行期库)
ANSI/Unicode 操作函数以lstr开头 lstrcpy(Windows函数)
所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:

#ifdef UNICODE
 #define CreateWindowEx CreateWindowExW
 #else
 #define CreateWindowEx CreateWindowExA
 #endif // !UNICODE

如何表示Unicode字符串常量

ANSI "string"
Unicode L"string"
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }

关于_T及L

_T 会根据你工程的设置自动转换UNICODE和非UNICODE,L 就是转为UNICODE。
Visual C++里边定义字符串的时候,用_T来保证兼容性,是一种数据类型,但是它不会产生结果,被编译系统的预处理系统来解释,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。

_T是将字符串转换为TCHAR,TCHAR是一个宏定义,当定义了UNICODE时TCHAR等同于WCHAR,否则等同于CHAR。为了和以后的平台兼容,建议使用TCHAR,而不要使用普通的CHAR。例子:TCHAR s = _T("FSDF")。L将字符串转换为WCHAR,用于需要UNICODE的环境。例子:WCHAR s = L"FSDF" 。

LPCTSTR和CString的关系

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 *,在之前看到TCHAR为ANSI/Unicode通用数据类型,当定义了UNICODE时TCHAR等同于WCHAR,否则等同于CHAR。

常量字符串ansi和unicode的区分是由宏_T来决定的。但是用_T("abcd")时, 字符串"abcd"就会根据编译时的是否定一_UNICODE来决定是char 还是 w_char。 同样,TCHAR 也是相同目的字符宏。
ANSI情况下,LPCTSTR 就是 const char , 是常量字符串(不能修改的);而LPTSTR就是char , 即普通字符串(非常量,可修改的)。

CString和LPCTSTR

CString和LPCTSTR可以说通用。 原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。
CString和LPCTSTR这两种都是基本类型, 而CString 是 C++类, 兼容这两种基本类型是最起码的任务了。
当你需要一个const char 而传入了CString时, C++编译器自动调用 CString重载的操作符 LPCTSTR()来进行隐式的类型转换。
当需要CString , 而传入了const char 
时(其实 char * 也可以),C++编译器则自动调用CString的构造函数来构造临时的CString对象。

CString 转LPCTSTR:
CString cStr;
const char *lpctStr=(LPCTSTR)cStr;
LPCTSTR转CString:
LPCTSTR lpctStr;
CString cStr=lpctStr;

如何在Unicode与ANSI之间转换字符串

Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。

CString -->char *

CString str1 =_T("123");
int len = WideCharToMultiByte(CP_ACP,0,str1,-1,NULL,0,NULL,NULL);
char *ptxtTemp = new char[len +1];
WideCharToMultiByte(CP_ACP,0,str1,-1,ptxtTemp,len,NULL,NULL );

//...
delete[] ptxtTemp;

char * -->CString

char *p ="test";  
CString str(p);
char * pFileName = "你好,世界!Hello,World";
//计算char *数组大小,以字节为单位,一个汉字占两个字节
int charLen = strlen(pFileName);
//计算多字节字符的大小,按字符计算。
int len = MultiByteToWideChar(CP_ACP,0,pFileName,charLen,NULL,0);
//为宽字节字符数组申请空间,数组大小为按字节计算的多字节字符大小
TCHAR *buf = new TCHAR[len + 1];
//多字节编码转换成宽字节编码
MultiByteToWideChar(CP_ACP,0,pFileName,charLen,buf,len);
buf[len] = ‘\0‘; //添加字符串结尾,注意不是len+1
//将TCHAR数组转换为CString
CString pWideChar;
pWideChar.Append(buf);
//删除缓冲区
delete []buf;

转载请注明作者Jason Ding及其出处
Github博客主页(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)

【编程拾遗】VC++中LPCTSTR、CString、char *、string之间的相互转换