1, 将参数从"const char *"转换为"LPCTSTR"
1 使用_T、L、TEXT等转换宏 2 MyFunZipCp(_T("C:\\SY.txt"),_T("C:\\SY.ZIP"),false); 3 或者 4 MyFunZipCp(L"C:\\SY.txt",L"C:\\SY.ZIP",false); 5 或者 6 MyFunZipCp(TEXT("C:\\SY.txt"),TEXT("C:\\SY.ZIP"),false);
2, LPCTSTR和LPTSTR和char *究竟有什么区别
"T"的含义就是如果定义了UNICODE,它就是宽字符版本,否则就是Ansi版本。
LPTSTR:
如果定义了UNICODE宏,那么LPTSTR = wchar_t*否则LPTSTR = char*
如果定义了UNICODE宏,那么LPCTSTR = const wchar_t*,否则LPCSTR = const char*
MSDN上的DataType上是这么说的,LPTSTR是什么呢?
#ifdef UNICODE typedef LPWSTR LPTSTR; #else typedef LPSTR LPTSTR; #endif
在unicode编码中(VS2010,VS2013等):而LPWSTR是针对wchar_t的
在ansi编码中(VC6):LPSTR是针对char的,
typedef CHAR *LPSTR;typedef char CHAR;可见如果没有定义UNICODE的话, char *就是LPTSTR,而const char *就是LPCTSTR,
那个T表示的是TCHAR(char[ascii],wchar_t[UNICODE])
所以,可以再程序中:使用char* pStr;
(LPTSTR) pStr, 直接进行转化,(LPSTR或者LPWSTR的情形)。
1 //Unicode 版本 2 3 typedef wchar_t WCHAR; 4 typedef WCHAR *PWCHAR; 5 typedef WCHAR *LPWCH, *PWCH; 6 typedef CONST WCHAR *LPCWCH, *PCWCH; 7 typedef WCHAR *NWPSTR; 8 typedef WCHAR *LPWSTR, *PWSTR; 9 typedef WCHAR UNALIGNED *LPUWSTR, *PUWSTR; 10 11 typedef CONST WCHAR *LPCWSTR, *PCWSTR; 12 typedef CONST WCHAR UNALIGNED *LPCUWSTR, *PCUWSTR; 13 14 // Ansi版本 15 16 typedef CHAR *PCHAR; 17 typedef CHAR *LPCH, *PCH; 18 19 typedef CONST CHAR *LPCCH, *PCCH; 20 typedef CHAR *NPSTR; 21 typedef CHAR *LPSTR, *PSTR; 22 typedef CONST CHAR *LPCSTR, *PCSTR; 23 24 #ifdef UNICODE(VS2013等IDE) 25 typedef WCHAR TCHAR, *PTCHAR; 26 typedef WCHAR TBYTE , *PTBYTE ; 27 typedef LPWSTR LPTCH, PTCH; 28 typedef LPWSTR PTSTR, LPTSTR; 29 typedef LPCWSTR PCTSTR, LPCTSTR; 30 typedef LPUWSTR PUTSTR, LPUTSTR; 31 typedef LPCUWSTR PCUTSTR, LPCUTSTR; 32 typedef LPWSTR LP; 33 #else(VC6的开发环境) 34 typedef char TCHAR, *PTCHAR; 35 typedef unsigned char TBYTE , *PTBYTE ; 36 typedef LPSTR LPTCH, PTCH; 37 typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR; 38 typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR; 39 #endif
可以直接通过LPTSTR或者LPCTSTR 进行直接类型转化为适应于:Unicode编码下:LPWSTR,LPCWSTR 或者ANSI编码下:LPSTR, LPCSTR 的情形
因为:LPTSTR,LPCTSTR可以通过编译器的当前的编码类型自动转换为相应的编码。
但是:当LPTSTR,LPCTSTR与直接的char* 或者w_char* 转化时,需要特别注意。
在进行字符相关的API调用时:
(1)直接转化成相应的类型;
(2)可以采取“中庸”的API同时可以兼容:char* 或者w_char*
如: strcpy、wcscpy与_tcscpy
C++标准库函数提供了字符和字符串的操作函数,并提供了其UNICODE版本,如:
- char *strcpy(char *strDestination, const char *strSource);
- wchar_t *wcscpy(wchar_t *strDestination, const wchar_t *strSource);
wcscpy()即为strcpy()的宽字符版本,与_T类似的,Visual C++提供了类似的同名函数:
#ifdef UNICODE #define _tcscpy wcscpy #else #define _tcscpy strcpy #endif
这样可以直接使用:_tcscpy来代替:strcpy用于asci等编码情形,或者wcscpy用于UNICode编码情形。
因为:TCHAR也可以适用于不同给的编码情形,所以采用TCHAR在实际的不同字符编码体系开发中比较好。
因此我们建议这样书写代码: TCHAR src[] = _T("学习C++"); TCHAR dest[20]; _tcscpy(dest, src);
比如,在使用printf()的时候,我会尝试使用_tprintf()。
同样的版本问题一样会困扰着main()函数:
- main( int argc, char *argv[ ], char *envp[ ]);
- wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ]);
再来看_tmain()的定义: #ifdef UNICODE #define _tmain wmain #define _tWinMain wWinMain #else #define _tmain main #define _tWinMain WinMain #endif
这就是为什么Win32控制台项目默认输出,提供一个_tmain()函数的缘故。
刨根问底
Microsoft 专用
为了简化各种国际市场的代码开发, Microsoft 运行库提供许多数据类型、例程和其他对象提供特定于 Microsoft 的 “一般文本映射”。
这些映射。 TCHAR.H. 定义。 可以使用这些名称映射到可用于任何这三个生成字符集的通用代码:
ASCII (SBCS) 使用 #define 语句,中, MBCS 或 Unicode,根据一个清单常数您定义。 一般文本映射是不符合 ANSI 的 Microsoft 扩展。
char*风格的参数不支持Unicode
CString,string,char*之间的转换
这三种类型各有各的优点,比如CString比较灵活,是基于MFC常用的类 型,安全性也最高,但可移植性最差。string是使用STL时必不可少的类型,所以是做工程时必须熟练掌握的;char*是从学习C语言开始就已经和我 们形影不离的了,有许多API都是以char*作为参数输入的。所以熟练掌握三者之间的转换十分必要。
以下我用简单的图示指出三者之间的关系,并以标号对应转换的方法。
1 1 string to CString 2 CString.format("%s",string.c_str()); 3 4 2 CString to string 5 string str(CString.GetBuffer(str.GetLength())); 6 7 3 string to char * 8 char *p=string.c_str(); 9 10 4 char * to string 11 string str(char*); 12 13 5 CString to char * 14 strcpy(char,CString,sizeof(char)); 15 16 6 char * to CString 17 CString.format("%s",char*); 18 CString的format方法是非常好用的。string的c_str()也是非常常用的,但要注意和char *转换时,要把char定义成为const char*,这样是最安全的。 19 20 以上函数UNICODE编码也没问题:unicode下照用,加个_T()宏就行了,像这样子_T("%s")
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等宏基本上不需要啦
CString:我们首先要了解 CString 是一种很特殊的 C++ 对象,它里面包含了三个值:
(1)一个指向某个数据缓冲区的指针、
(2)一个是该缓冲中有效的字符记数以及
(3)一个缓冲区长度。有效字符数的大小可以是从0到该缓冲最大长度值减1之间的任何数(因为字符串结尾有一个NULL字符)。
字符记数和缓冲区长度被巧妙隐藏。:
LPCTSTR 操作符(或者更明确地说就是 TCHAR * 操作符)在 CString 类中被重载了,该操作符的定义是返回缓冲区的地址,因此,如果你需要一个指向 CString 的 字符串指针的话