目录directory. 1
MFC数据类型... 2
C++数据类型基础... 3
MFC/windows基本数据类型... 3
VC常用数据类型列表... 5
常用数据类型转化及操作... 8
1 数学类型变量与字符串相互转换(这些函数都在STDLIB.H里). 8
2.CString及string,char *与其他数据类型的转换和操作... 9
3.BSTR、_bstr_t与CComBSTR. 11
4.(引)VARIANT 、_variant_t 与 COleVariant. 11
VC++.NET中字符串之间的转换... 13
一、BSTR、LPSTR和LPWSTR. 13
二、CString、CStringA 和 CStringW. 13
三、VARIANT、COleVariant 和_variant_t. 13
四、CComBSTR和_bstr_t. 15
五、BSTR、char*和CString转换... 15
六、结语... 17
标准C或C++没有的数据类型
数据类型 |
定义 |
BOOL |
布尔变量,实际上是UINT(布尔值,不是TRUE就是FALSE) |
COLORREF |
用作颜色索引的32位整数 |
BSTR |
32-bit字符指针 |
BYTE |
8-bit整数,未带正负号 |
DWORD |
32位的无符号整数 |
HANDLE |
32位的无符号整数,用作句柄 |
HINSTANCE |
32位的无符号整数,用作实例句柄 |
HWND |
32位的无符号整数,用作窗口句柄 |
HDC |
一个设备描述背景的句柄 |
LONG |
32位带符号整数 |
LPARAM |
32位整数,用作窗口函数或者其他回调函数的参数之一 |
LPCSTR |
指向一个字符串常量的32位指针 |
LPSTR |
定义一个线性的32位字符串指针 |
LPCTSTR |
32-bit指针,指向一个常数字符串。此字符串可移植到Unicode和DBCS(双字节字集) |
LPTSTR: |
32-bit指针,指向一个字符串。此字符串可移植到Unicode和DBCS(双字节字集) |
LPVOID |
32-bit字符指针,指向一个未指定类型的数据 |
LPRESULT |
32-bit数值,作为窗口函数或callback函数的返回值 |
LPCRECT |
32-bit指针,指向一个不边的RECT结构 |
|
|
UINT |
定义一个新的Win32数据类型,它会把一个参数强制转换成Windows3.x应用中的16位值 或Win32应用中的32位值 |
WCHAR |
声明一个16位的UNICODE字符,用来表示世界上所有已知的书写语言的符号 |
WNDPROC |
32-bit指针,指向一个窗口函数 |
WORD |
16位的无符号整数 |
WPARAM |
32位整数,用作窗口函数或者其他回调函数的参数之一(在Windows3.x中为16位值) |
unsigned : 无符号类型
signed : 有符号类型
void : 无类型
sizeof : 取得指定类型的所占用的范围
typedef : 为某种类型取一别名
类型标识符 |
类型说明 |
长度字节) |
范围 |
备注 |
char |
字符型 |
1 |
-128 ~ 127 |
-27 ~ (27 -1) |
unsigned char |
无符字符型 |
1 |
0 ~ 255 |
0 ~ (28 -1) |
short int |
短整型 |
2 |
-32768 ~ 32767 |
2-15 ~ (215 - 1) |
unsigned short int |
无符短整型 |
2 |
0 ~ 65535 |
0 ~ (216 - 1) |
int |
整型 |
4 |
-2147483648 ~ 2147483647 |
-231 ~ (231 - 1) |
unsigned int |
无符整型 |
4 |
0 ~ 4294967295 |
0 ~ (232-1) |
float |
实型(单精度) |
4 |
1.18*10-38 ~ 3.40*1038 |
7位有效位 |
double |
实型(双精度) |
8 |
2.23*10-308 ~ 1.79*10308 |
15位有效位 |
long double |
实型(长双精度) |
10 |
3.37*10-4932 ~ 1.18*104932 |
19位有效位 |
windef.h
Abstract:Basic Windows Type Definitions ,included in windows.h
winnt.h
Abstract:This module defines the 32-Bit Windows types and constants that are
defined by NT, but exposed through the Win32 API.
afx.h
Abstract:This is a part of the Microsoft Foundation Classes C++ library.
#define FALSE 0 afx.h
#define TRUE 1 afx.h
#define NULL 0 afx.h
typedef void VOID winnt.h
//短整型typedef unsigned short
typedef unsigned short USHORT; windef.h
typedef unsigned short WORD; windef.h
typedef unsigned short wchar_t
typedef short SHORT; winnt.h
//整型typedef int
typedef int BOOL; 取值为TRUE or FALSE windef.h
typedef int INT; windef.h
typedef unsigned int UINT; 定义一个新的Win32数据类型,它会把一个参数强制转换成Windows3.x应用中的16位值 或Win32应用中的32位值windef.h
//长整型typedef long
typedef unsigned long ULONG; windef.h
typedef unsigned long DWORD; windef.h
typedef DWORD COLORREF; windef.h
typedef long LONG; winnt.h
typedef __int64 LONGLONG; winnt.h
typedef unsigned __int64 ULONGLONG; winnt.h
typedef ULONGLONG DWORDLONG; winnt.h
//浮点型
typedef float FLOAT; windef.h
typedef double DOUBLE; wtypes.h
//字符类型typedef char
typedef char CHAR/CCHAR; winnt.h
typedef unsigned char UCHAR; windef.h
typedef unsigned char BYTE; windef.h
typedef wchar_t WCHAR; 声明一个16位的UNICODE字符,用来表示世界上所有已知的书写语言的符号winnt.h
typedef WCHAR TCHAR, *PTCHAR; winnt.h
//指向字符串的指针类型LP*
/*以下为winnt.h的部分内容*/
// UNICODE (Wide Character) types
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR;
// ANSI (Multi-byte Character) types
typedef CHAR *PCHAR, *LPCH, *PCH;
typedef __nullterminated CHAR *NPSTR, *LPSTR, *PSTR;
指向Windows字符串(以空字符结束)的32位指针char*
typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
指向Windows常字符串(以空字符结束)的32位指针const char*
// Neutral ANSI/UNICODE types and macros
#ifdef UNICODE // r_winnt
#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
typedef LPWSTR PTSTR, LPTSTR;
指向Windows字符串(以空字符结束)的32位指针,用于移植到双字节字符集
LPTSTR For Unicode platforms,it is LPWSTR,For ANSI and DBCS platforms,it is LPSTR
typedef LPCWSTR PCTSTR, LPCTSTR;
指向Windows常字符串(以空字符结束)的32位指针const char* ,用于移植到双字节字符集
LPCTSTR For Unicode platforms,it is LPCWSTR,For ANSI and DBCS platforms,it is LPCSTR
typedef LPWSTR LP;
#define __TEXT(quote) L##quote // r_winnt
/*以上为winnt.h的部分内容*/
typedef WCHAR OLECHAR; wtypes.h
typedef /* [wire_marshal] */ OLECHAR *BSTR; unsigned short* wtypes.h
//函数参数、返回值类型
typedef UINT_PTR WPARAM; 窗口函数或callback函数的一个参数,在Win16中是16-bit,在Win32中是32-bit windef.h
typedef LONG_PTR LPARAM; 32位窗口函数或callback函数的一个参数windef.h
typedef LONG_PTR LRESULT; 32位作为窗口函数或callback函数的返回值windef.h
//指向函数的指针类型__stdcall
typedef int (WINAPI *PROC)();PROC指向回调函数的指针
typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
WNDPROC指向在应用程序中定义的窗口过程的指针
#define CALLBACK __stdcall windef.h
#define WINAPI __stdcall windef.h
#define WINAPIV __cdecl windef.h
#define APIENTRY WINAPI windef.h
#define APIPRIVATE __stdcall windef.h
#define PASCAL __stdcall windef.h
typedef void far *LPVOID; 指向任意类型的指针windef.h
//Windows句柄类型HANDLE32位的无符号整数,用于标识
窗口句柄HWND 实例句柄HINSTANCE 光标句柄HCURSOR 图标句柄HICON 位图句柄HBITMAP 菜单句柄HMENU 设备描述句柄HDC 钢笔句柄HPEN 画刷句柄HBRUSH 字体句柄HFONT 文件句柄HFILE
|
Type |
Default Size |
Description |
基础类型(全是小写) |
说明:这些基础数据类型对于MFC还是API都是被支持的 |
||
boolean |
unsigned 8 bit , |
取值TRUE/FALSE |
|
byte |
unsigned 8 bit, |
整数,输出按字符输出 |
|
char |
unsigned 8 bit, |
字符 |
|
double |
signed 64 bit |
浮点型 |
|
float |
signed32 bit |
浮点型 |
|
handle_t |
|
Primitive handle type |
|
hyper |
signed 64 bit |
整型 |
|
int |
signed 32 bit |
整型 |
|
long |
signed 32 bit |
整型 |
|
short |
signed 16 bit |
整型 |
|
small |
signed 8 bit |
整型 |
|
void * |
32-bit |
指向未知类型的指针 |
|
wchar_t |
unsigned 16 bit |
16位字符,比char可容纳更多的字符 |
|
Win32 PI 常用数据类型(全是大写) |
说明: 这些Win32API支持的简单数据类型主要是用来定义函数返回值,消息参数,结构成员。这类数据类型大致可以分为五大类:字符型、布尔型、整型、指针型和句柄型(?). 总共大概有100多种不同的类型, |
||
BOOL/BOOLEAN |
8bit,TRUE/FALSE |
布尔型 |
|
BYTE |
unsigned 8 bit |
|
|
BSTR CComBSTR _bstr_t |
32 bit |
BSTR是指向字符串的32位指针 是对BSTR的封装 是对BSTR的封装 |
|
CHAR |
8 bit |
(ANSI)字符类型 |
|
COLORREF |
32 bit |
RGB颜色值 整型 |
|
DWORD |
unsigned 32 bit |
整型 |
|
FLOAT |
float型 |
float型 |
|
HANDLE |
|
Object句柄 |
|
HBITMAP |
|
bitmap句柄 |
|
HBRUSH |
|
brush句柄 |
|
HCURSOR |
|
cursor句柄 |
|
HDC |
|
设备上下文句柄 |
|
HFILE |
|
OpenFile打开的File句柄 |
|
HFONT |
|
font句柄 |
|
HHOOK |
|
hook句柄 |
|
HKEY |
|
注册表键句柄 |
|
HPEN |
|
pen句柄 |
|
HWND |
|
window句柄 |
|
INT |
-------- |
-------- |
|
LONG |
-------- |
--------- |
|
LONGLONG |
|
64位带符号整型 |
|
LPARAM |
32 bit |
消息参数 |
|
LPBOOL |
|
BOOL型指针 |
|
LPBYTE |
|
BYTE型指针 |
|
LPCOLOREF |
|
COLORREF型指针 |
|
LPCSTR/LPSTR/PCSTR |
|
指向8位(ANSI)字符串类型指针 |
|
LPCWSTR/LPWSTR/PCWSTR |
|
指向16位Unicode字符串类型 |
|
LPCTSTR/LPTSTR/PCTSTR |
|
指向一8位或16位字符串类型指针 |
|
LPVOID |
|
指向一个未指定类型的32位指针 |
|
LPDWORD |
|
指向一个DWORD型指针 |
|
其他相似类型: LPHANDLE、LPINT、LPLONG、LPWORD、LPRESULT PBOOL、PBOOLEAN、PBYTE、PCHAR、PDWORD、PFLOAT、PHANDLE、PINT、PLONG、PSHORT…… 说明:(1)在16位系统中 LP为16bit,P为8bit,在32位系统中都是32bit(此时等价) (2)LPCSTR等 中的C指Const,T表示TCHAR模式即可以工作在ANSI下也可UNICODE |
|||
SHORT |
usigned |
整型 |
|
其他UCHAR、UINT、ULONG、ULONGLONG、USHORT为无符号相应类型 |
|||
TBYTE |
|
WCHAR型或者CHAR型 |
|
TCHAR |
|
ANSI与unicode均可 |
|
VARIANT _variant_t COleVariant |
|
一个结构体参考OAIDL.H _variant_t是VARIANT的封装类 COleVariant也是VARIANT的封装类 |
|
|
|
|
|
|
|
|
|
WNDPROC |
|
指向一个窗口过程的32位指针 |
|
WCHAR |
|
16位Unicode字符型 |
|
WORD |
|
16位无符号整型 |
|
WPARAM |
|
消息参数 |
|
MFC独有数据类型 |
下面两个数据类型是微软基础类库中独有的数据类型 |
||
POSITION |
标记集合中一个元素的位置的值,被MFC中的集合类所使用 |
||
LPCRECT |
指向一个RECT结构体常量(不能修改)的32位指针 |
||
CString |
其实是MFC中的一个类 |
||
说明: (1)-------表示省略 (2)1Byte=8Bit, 字与机器有关,在8位系统中:字=1字节,16位系统中,1字=2字节,32位中:1字=4字节, 64位中1字=8字节.不要搞混这些概念. |
1 数学类型变量与字符串相互转换(这些函数都在STDLIB.H里)
(1)将数学类型转换为字符串可以用以下一些函数:
举例: _CRTIMP char * __cdecl _itoa(int, char *, int);//这是一个将数字转换为一个字符串类型的函数,最后一个int表示转换的进制
如以下程序:
int iTyep=3;
char *szChar;
itoa(iType,szChar,2);
cout<
类似函数列表:
_CRTIMP char * __cdecl _itoa(int, char *, int);//为了完整性,也列在其中
_CRTIMP char * __cdecl _ultoa(unsigned long, char *, int);
_CRTIMP char * __cdecl _ltoa(long, char *, int);
_CRTIMP char * __cdecl _i64toa(__int64, char *, int);
_CRTIMP char * __cdecl _ui64toa(unsigned __int64, char *, int);
_CRTIMP wchar_t * __cdecl _i64tow(__int64, wchar_t *, int);
_CRTIMP wchar_t * __cdecl _ui64tow(unsigned __int64, wchar_t *, int);
_CRTIMP wchar_t * __cdecl _itow (int, wchar_t *, int);//转换为长字符串类型
_CRTIMP wchar_t * __cdecl _ltow (long, wchar_t *, int);
_CRTIMP wchar_t * __cdecl _ultow (unsigned long, wchar_t *, int);
还有很多,请自行研究
(2)将字符串类型转换为数学类型变量可以用以下一些函数:
举例: _CRTIMP int __cdecl atoi(const char *);//参数一看就很明了
char *szChar=” 88” ;
int temp(0);
temp=atoi(szChar);
cout<
类似的函数列表:
_CRTIMP int __cdecl atoi(const char *);
_CRTIMP double __cdecl atof(const char *);
_CRTIMP long __cdecl atol(const char *);
_CRTIMP long double __cdecl _atold(const char *);
_CRTIMP __int64 __cdecl _atoi64(const char *);
_CRTIMP double __cdecl strtod(const char *, char **);//
_CRTIMP long __cdecl strtol(const char *, char **, int);//
_CRTIMP long double __cdecl _strtold(const char *, char **);
_CRTIMP unsigned long __cdecl strtoul(const char *, char **, int);
_CRTIMP double __cdecl wcstod(const wchar_t *, wchar_t **);//长字符串类型转换为数学类型
_CRTIMP long __cdecl wcstol(const wchar_t *, wchar_t **, int);
_CRTIMP unsigned long __cdecl wcstoul(const wchar_t *, wchar_t **, int);
_CRTIMP int __cdecl _wtoi(const wchar_t *);
_CRTIMP long __cdecl _wtol(const wchar_t *);
_CRTIMP __int64 __cdecl _wtoi64(const wchar_t *);
还有很多,请自行研究
2.CString及string,char *与其他数据类型的转换和操作
(1)CString,string,char*的综合比较(这部分CSDN上的作者joise的文章
<< CString,string,char*的综合比较>>写的很详细,请大家在仔细阅读他的文章.
地址: http://blog.csdn.net/joise/
或参考附录:
(2)转换:
●数学类型与CString相互转化
数学类型转化为CString
可用Format函数,举例:
CString s;
int i = 64;
s.Format("%d", i)
CString转换为数学类型:举例CString strValue("1.234");
double dblValue;
dblValue = atof((LPCTSTR)strValue);
●CString与char*相互转换举例
CString strValue(“Hello”);
char *szValue;
szValue=strValue.GetBuffer(szValue);
也可用(LPSTR)(LPCTSTR)对CString// 进行强制转换.
szValue=(LPSTR)(LPCTSTR)strValue;
反过来可直接赋值:
char *szChar=NULL;
CString strValue;
szChar=new char[10];
memset(szChar,0,10);
strcpy(szChar,”Hello”);
strValue=szChar;
●CString 与 BSTR 型转换
CString 型转化成 BSTR 型
当我们使用 ActiveX 控件编程时,经常需要用到将某个值表示成 BSTR 类型.BSTR 是一种记数字符串,Intel平台上的宽字符串(Unicode),并且可以包含嵌入的 NULL 字符。
可以调用 CString 对象的 AllocSysString 方法将 CString 转化成 BSTR:
CString str;
str = .....; // whatever
BSTR bStr = str.AllocSysString();
BSTR型转换为CString
如果你在 UNICODE 模式下编译代码,你可以简单地写成:
CString convert(BSTR bStr)
{
if(bStr == NULL)
return CString(_T(""));
CString s(bStr); // in UNICODE mode
return s;
}
如果是 ANSI 模式
CString convert(BSTR b)
{
CString s;
if(b == NULL)
return s; // empty for NULL BSTR
#ifdef UNICODE
s = b;
#else
LPSTR p = s.GetBuffer(SysStringLen(b) + 1);
::WideCharToMultiByte(CP_ACP, // ANSI Code Page
0, // no flags
b, // source widechar string
-1, // assume NUL-terminated
p, // target buffer
SysStringLen(b)+1, // target buffer length
NULL, // use system default char
NULL); // don''t care if default used
s.ReleaseBuffer();
#endif
return s;
}
●VARIANT 型转化成 CString 型
VARIANT 类型经常用来给 COM 对象传递参数,或者接收从 COM 对象返回的值。你也能自己编写返回 VARIANT 类型的方法,函数返回什么类型依赖可能(并且常常)方法的输入参数(比如,在自动化操作中,依赖与你调用哪个方法。IDispatch::Invoke 可能返回(通过其一个参数)一个包含有BYTE、WORD、float、double、date、BSTR 等等 VARIANT 类型的结果,(详见 MSDN 上的 VARIANT 结构的定义)。在下面的例子中,假设 类型是一个BSTR的变体,也就是说在串中的值是通过 bsrtVal 来引用,其优点是在 ANSI 应用中,有一个构造函数会把 LPCWCHAR 引用的值转换为一个 CString(见 BSTR-to-CString 部分)。在 Unicode 模式中,将成为标准的 CString 构造函数,参见对缺省::WideCharToMultiByte 转换的告诫,以及你觉得是否可以接受(大多数情况下,你会满意的)。VARIANT vaData;
vaData = m_com.YourMethodHere();
ASSERT(vaData.vt == VT_BSTR);
CString strData(vaData.bstrVal);
你还可以根据 vt 域的不同来建立更通用的转换例程。为此你可能会考虑:
CString VariantToString(VARIANT * va)
{
CString s;
switch(va->vt)
{ /* vt */
case VT_BSTR:
return CString(vaData->bstrVal);
case VT_BSTR | VT_BYREF:
return CString(*vaData->pbstrVal);
case VT_I4:
s.Format(_T("%d"), va->lVal);
return s;
case VT_I4 | VT_BYREF:
s.Format(_T("%d"), *va->plVal);
case VT_R8:
s.Format(_T("%f"), va->dblVal);
return s;
... 剩下的类型转换由读者自己完成
default:
ASSERT(FALSE); // unknown VARIANT type (this ASSERT is optional)
return CString("");
} /* vt */
}
3.BSTR、_bstr_t与CComBSTR
CComBSTR、_bstr_t是对BSTR的封装,BSTR是指向字符串的32位指针。
char *转换到BSTR可以这样:
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上头文件comutil.h
反之可以使用char *p=_com_util::ConvertBSTRToString(b);
4.(引)VARIANT 、_variant_t 与 COleVariant
VARIANT的结构可以参考头文件VC98/Include/OAIDL.H中关于结构体tagVARIANT的定义。
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
VARIANT va;
int a=2001;
va.vt=VT_I4;///指明整型数据
va.lVal=a; ///赋值
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:
unsigned char bVal; VT_UI1
short iVal; VT_I2
long lVal; VT_I4
float fltVal; VT_R4
double dblVal; VT_R8
VARIANT_BOOL boolVal; VT_BOOL
SCODE scode; VT_ERROR
CY cyVal; VT_CY
DATE date; VT_DATE
BSTR bstrVal; VT_BSTR
IUnknown FAR* punkVal; VT_UNKNOWN
IDispatch FAR* pdispVal; VT_DISPATCH
SAFEARRAY FAR* parray; VT_ARRAY|*
unsigned char FAR* pbVal; VT_BYREF|VT_UI1
short FAR* piVal; VT_BYREF|VT_I2
long FAR* plVal; VT_BYREF|VT_I4
float FAR* pfltVal; VT_BYREF|VT_R4
double FAR* pdblVal; VT_BYREF|VT_R8
VARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL
SCODE FAR* pscode; VT_BYREF|VT_ERROR
CY FAR* pcyVal; VT_BYREF|VT_CY
DATE FAR* pdate; VT_BYREF|VT_DATE
BSTR FAR* pbstrVal; VT_BYREF|VT_BSTR
IUnknown FAR* FAR* ppunkVal; VT_BYREF|VT_UNKNOWN
IDispatch FAR* FAR* ppdispVal; VT_BYREF|VT_DISPATCH
SAFEARRAY FAR* FAR* pparray; VT_ARRAY|*
VARIANT FAR* pvarVal; VT_BYREF|VT_VARIANT
void FAR* byref; VT_BYREF
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
例如:
long l=222;
ing i=100;
_variant_t lVal(l);
lVal = (long)i;
COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
COleVariant v3 = "字符串", v4 = (long)1999;
CString str =(BSTR)v3.pbstrVal;
long i = v4.lVal;
一、BSTR、LPSTR和LPWSTR
在Visual C++.NET的所有编程方式中,我们常常要用到这样的一些基本字符串类型,如BSTR、LPSTR和LPWSTR等。之所以出现类似上述的这些数据类型,是因为不同编程语言之间的数据交换以及对ANSI、Unicode和多字节字符集(MBCS)的支持。
那么什么是BSTR、LPSTR以及LPWSTR呢?
BSTR(Basic STRing,Basic字符串)是一个OLECHAR*类型的Unicode字符串。它被描述成一个与自动化相兼容的类型。由于操作系统提供相应的 API函数(如SysAllocString)来管理它以及一些默认的调度代码,因此BSTR实际上就是一个COM字符串,但它却在自动化技术以外的多种场合下得到广泛使用。图1描述了BSTR的结构,其中DWORD值是字符串中实际所占用的字节数,且它的值是字符串中Unicode字符的两倍。
LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。LPSTR被定义成是一个指向以NULL(‘/ 0’ )结尾的8位ANSI 字符数组指针,而LPWSTR是一个指向以NULL结尾的16位双字节字符数组指针。在VC++中,还有类似的字符串类型,如LPTSTR、 LPCTSTR等,它们的含义如图2所示。
例如,LPCTSTR是指“long pointer to a constant generic string”,表示“一个指向一般字符串常量的长指针类型”,与C/C++的const char*相映射,而LPTSTR映射为 char*。
一般地,还有下列类型定义:
#ifdef UNICODE
typedef LPWSTR LPTSTR;
typedef LPCWSTR LPCTSTR;
#else
typedef LPSTR LPTSTR;
typedef LPCSTR LPCTSTR;
#endif
二、CString、CStringA 和 CStringW
Visual C++.NET中将CStringT作为ATL和MFC的共享的“一般”字符串类,它有CString、CStringA和CStringW三种形式,分别操作不同字符类型的字符串。这些字符类型是TCHAR、char和wchar_t。TCHAR在Unicode平台中等同于WCHAR(16位 Unicode字符),在ANSI中等价于char。wchar_t通常定义为unsigned short。由于CString在MFC应用程序中经常用到,这里不再重复。
三、VARIANT、COleVariant 和_variant_t
在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。下面让我们来看看OAIDL.H文件中VARIANT定义的一个简化版:
struct tagVARIANT {
VARTYPE vt;
union {
short iVal; // VT_I2.
long lVal; // VT_I4.
float fltVal; // VT_R4.
double dblVal; // VT_R8.
DATE date; // VT_DATE.
BSTR bstrVal; // VT_BSTR.
…
short * piVal; // VT_BYREF|VT_I2.
long * plVal; // VT_BYREF|VT_I4.
float * pfltVal; // VT_BYREF|VT_R4.
double * pdblVal; // VT_BYREF|VT_R8.
DATE * pdate; // VT_BYREF|VT_DATE.
BSTR * pbstrVal; // VT_BYREF|VT_BSTR.
};
};
显然,VARIANT类型是一个C结构,它包含了一个类型成员vt、一些保留字节以及一个大的union类型。例如,如果vt为VT_I2,那么我们可以从iVal中读出VARIANT的值。同样,当给一个VARIANT变量赋值时,也要先指明其类型。例如:
VARIANT va;
:: VariantInit(&va); // 初始化
int a = 2002;
va.vt = VT_I4; // 指明long数据类型
va.lVal = a; // 赋值
为了方便处理VARIANT类型的变量,Windows还提供了这样一些非常有用的函数:
VariantInit —— 将变量初始化为VT_EMPTY;
VariantClear —— 消除并初始化VARIANT;
VariantChangeType —— 改变VARIANT的类型;
VariantCopy —— 释放与目标VARIANT相连的内存并复制源VARIANT。
COleVariant类是对VARIANT结构的封装。它的构造函数具有极为强大大的功能,当对象构造时首先调用VariantInit进行初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与VARIANT类型转换中为我们提供极大的方便。例如下面的代码:
COleVariant v1("This is a test"); // 直接构造
COleVariant v2 = "This is a test";
// 结果是VT_BSTR类型,值为"This is a test"
COleVariant v3((long)2002);
COleVariant v4 = (long)2002;
// 结果是VT_I4类型,值为2002
_variant_t是一个用于COM的VARIANT类,它的功能与COleVariant相似。不过在Visual C++.NET的MFC应用程序中使用时需要在代码文件前面添加下列两句:
#include "comutil.h"
#pragma comment( lib, "comsupp.lib" )
四、CComBSTR和_bstr_t
CComBSTR是对BSTR数据类型封装的一个ATL类,它的操作比较方便。例如:
CComBSTR bstr1;
bstr1 = "Bye"; // 直接赋值
OLECHAR* str = OLESTR("ta ta"); // 长度为5的宽字符
CComBSTR bstr2(wcslen(str)); // 定义长度为5
wcscpy(bstr2.m_str, str); // 将宽字符串复制到BSTR中
CComBSTR bstr3(5, OLESTR("Hello World"));
CComBSTR bstr4(5, "Hello World");
CComBSTR bstr5(OLESTR("Hey there"));
CComBSTR bstr6("Hey there");
CComBSTR bstr7(bstr6);
// 构造时复制,内容为"Hey there"
_bstr_t是是C++对BSTR的封装,它的构造和析构函数分别调用SysAllocString和SysFreeString函数,其他操作是借用BSTR API函数。与_variant_t相似,使用时也要添加comutil.h和comsupp.lib。
五、BSTR、char*和CString转换
(1) char*转换成CString
若将char*转换成CString,除了直接赋值外,还可使用CString::Format进行。例如:
char chArray[] = "This is a test";
char * p = "This is a test";
或
LPSTR p = "This is a test";
或在已定义Unicode应的用程序中
TCHAR * p = _T("This is a test");
或
LPTSTR p = _T("This is a test");
CString theString = chArray;
theString.Format(_T("%s"), chArray);
theString = p;
(2) CString转换成char*
若将CString类转换成char*(LPSTR)类型,常常使用下列三种方法:
方法一,使用强制转换。例如:
CString theString( "This is a test" );
LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;
方法二,使用strcpy。例如:
CString theString( "This is a test" );
LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
_tcscpy(lpsz, theString);
需要说明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二个参数是 const wchar_t* (Unicode)或const char* (ANSI),系统编译器将会自动对其进行转换。
方法三,使用CString::GetBuffer。例如:
CString s(_T("This is a test "));
LPTSTR p = s.GetBuffer();
// 在这里添加使用p的代码
if(p != NULL) *p = _T('/0');
s.ReleaseBuffer();
// 使用完后及时释放,以便能使用其它的CString成员函数
(3) BSTR转换成char*
方法一,使用ConvertBSTRToString。例如:
#include
#pragma comment(lib, "comsupp.lib")
int _tmain(int argc, _TCHAR* argv[]){
BSTR bstrText = ::SysAllocString(L"Test");
char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
SysFreeString(bstrText); // 用完释放
delete[] lpszText2;
return 0;
}
方法二,使用_bstr_t的赋值运算符重载。例如:
_bstr_t b = bstrText;
char* lpszText2 = b;
(4) char*转换成BSTR
方法一,使用SysAllocString等API函数。例如:
BSTR bstrText = ::SysAllocString(L"Test");
BSTR bstrText = ::SysAllocStringLen(L"Test",4);
BSTR bstrText = ::SysAllocStringByteLen("Test",4);
方法二,使用COleVariant或_variant_t。例如:
//COleVariant strVar("This is a test");
_variant_t strVar("This is a test");
BSTR bstrText = strVar.bstrVal;
方法三,使用_bstr_t,这是一种最简单的方法。例如:
BSTR bstrText = _bstr_t("This is a test");
方法四,使用CComBSTR。例如:
BSTR bstrText = CComBSTR("This is a test");
或
CComBSTR bstr("This is a test");
BSTR bstrText = bstr.m_str;
方法五,使用ConvertStringToBSTR。例如:
char* lpszText = "Test";
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
(5) CString转换成BSTR
通常是通过使用CStringT::AllocSysString来实现。例如:
CString str("This is a test");
BSTR bstrText = str.AllocSysString();
…
SysFreeString(bstrText); // 用完释放
(6) BSTR转换成CString
一般可按下列方法进行:
BSTR bstrText = ::SysAllocString(L"Test");
CStringA str;
str.Empty();
str = bstrText;
或
CStringA str(bstrText);
(7) ANSI、Unicode和宽字符之间的转换
方法一,使用MultiByteToWideChar将ANSI字符转换成Unicode字符,使用WideCharToMultiByte将Unicode字符转换成ANSI字符。
方法二,使用“_T”将ANSI转换成“一般”类型字符串,使用“L”将ANSI转换成Unicode,而在托管C++环境中还可使用S将ANSI字符串转换成String*对象。例如:
TCHAR tstr[] = _T("this is a test");
wchar_t wszStr[] = L"This is a test";
String* str = S”This is a test”;
方法三,使用ATL 7.0的转换宏和类。ATL7.0在原有3.0基础上完善和增加了许多字符串转换宏以及提供相应的类,它具有如图3所示的统一形式:
其中,第一个C表示“类”,以便于ATL 3.0宏相区别,第二个C表示常量,2表示“to”,EX表示要开辟一定大小的缓冲。SourceType和DestinationType可以是A、 T、W和OLE,其含义分别是ANSI、Unicode、“一般”类型和OLE字符串。例如,CA2CT就是将ANSI转换成一般类型的字符串常量。下面是一些示例代码:
LPTSTR tstr= CA2TEX<16>("this is a test");
LPCTSTR tcstr= CA2CT("this is a test");
wchar_t wszStr[] = L"This is a test";
char* chstr = CW 2A (wszStr);
六、结语
几乎所有的程序都要用到字符串,而Visual C++.NET由于功能强大、应用广泛,因而字符串之间的转换更为频繁。本文几乎涉及到目前的所有转换方法。当然对于.NET框架来说,还可使用Convert和Text类进行不同数据类型以及字符编码之间的相互转换。