VC++常用数据类型及其操作详解
一.VC常用数据类型列表
二.常用数据类型转化
2.1数学类型变量与字符串相互转换
2.2 CString及string,char *与其他数据类型的转换和操作
●CString,string,char*的综合比较
●数学类型与CString相互转化
●CString与char*相互转换举例
●CString 与 BSTR 型转换
●VARIANT 型转化成 CString 型
2.3 BSTR、_bstr_t与CComBSTR
2.4 VARIANT 、_variant_t 与 COleVariant
附录CString及字符串转及操作详解
参考书籍:CSDN,<<MFC深入浅出(Second Edit)>>
一.VC常用数据类型列表
| 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 API 常 用 数 据 类 型
全 大 写 | 说明: 这些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字节.不要搞混这些概念.
二.常用数据类型转化及操作
2.1 数学类型变量与字符串相互转换(这些函数都在STDLIB.H里)
(1)将数学类型转换为字符串可以用以下一些函数:
举例: _CRTIMP char * __cdecl _itoa(int, char *, int);//这是一个将数字转换为一个字符串类型的函数,最后一个int表示转换的进制
如以下程序:
int iTyep=3;
char *szChar;
itoa(iType,szChar,2);
cout<<szChar;//输出为1010
类似函数列表:
_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<<temp;
类似的函数列表:
_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.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 */
}
2.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);
2.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 = CW2A(wszStr);
六、结语
几乎所有的程序都要用到字符串,而Visual C++.NET由于功能强大、应用广泛,因而字符串之间的转换更为频繁。本文几乎涉及到目前的所有转换方法。当然对于.NET框架来说,还可使用Convert和Text类进行不同数据类型以及字符编码之间的相互转换。
int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="程佩君";
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;
一、其它数据类型转换为字符串
-
短整型(int)
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); ///按二进制方式转换
- 长整型(long)
ltoa(l,temp,10); - 浮点数(float,double)
用fcvt可以完成转换,这是MSDN中的例子:
int decimal, sign;
char *buffer;
double source = 3.1415926535;
buffer = _fcvt( source, 7, &decimal, &sign );
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
decimal表示小数点的位置,sign表示符号:0为正数,1为负数 - CString变量
str = "2008北京奥运";
buf = (LPSTR)(LPCTSTR)str; - BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员");
char * buf = _com_util::ConvertBSTRToString(bstrValue);
SysFreeString(bstrValue);
AfxMessageBox(buf);
delete(buf); - CComBSTR变量
CComBSTR bstrVar("test");
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
AfxMessageBox(buf);
delete(buf); - _bstr_t变量
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
_bstr_t bstrVar("test");
const char *buf = bstrVar;///不要修改buf中的内容
AfxMessageBox(buf); - 通用方法(针对非COM数据类型)
用sprintf完成转换char buffer[200];char c = '1';int i = 35;long j = 1000;float f = 1.7320534f;sprintf( buffer, "%c",c);sprintf( buffer, "%d",i);sprintf( buffer, "%d",j);sprintf( buffer, "%f",f);
二、字符串转换为其它数据类型
strcpy(temp,"123");
- 短整型(int)
i = atoi(temp); - 长整型(long)
l = atol(temp); - 浮点(double)
d = atof(temp); - CString变量
CString name = temp; - BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员");
...///完成对bstrValue的使用
SysFreeString(bstrValue); - CComBSTR变量
CComBSTR类型变量可以直接赋值
CComBSTR bstrVar1("test");
CComBSTR bstrVar2(temp); - _bstr_t变量
_bstr_t类型的变量可以直接赋值
_bstr_t bstrVar1("test");
_bstr_t bstrVar2(temp);
三、其它数据类型转换到CString
使用CString的成员函数Format来转换,例如:
- 整数(int)
str.Format("%d",i); - 浮点数(float)
str.Format("%f",i); - 字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
str = username; - 对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
四、BSTR、_bstr_t与CComBSTR
- CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
char *转换到BSTR可以这样:
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
SysFreeString(bstrValue);
反之可以使用
char *p=_com_util::ConvertBSTRToString(b);
delete p;
具体可以参考一,二段落里的具体说明。
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
特别是_bstr_t,建议大家使用它。
五、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与常用数据的对应关系:
Byte 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. DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL. IUnknown FAR* punkVal; // VT_UNKNOWN. IDispatch FAR* pdispVal; // VT_DISPATCH. SAFEARRAY FAR* parray; // VT_ARRAY|*. Byte 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; // Generic ByRef. char cVal; // VT_I1. unsigned short uiVal; // VT_UI2. unsigned long ulVal; // VT_UI4. int intVal; // VT_INT. unsigned int uintVal; // VT_UINT. char FAR * pcVal; // VT_BYREF|VT_I1. unsigned short FAR * puiVal; // VT_BYREF|VT_UI2. unsigned long FAR * pulVal; // VT_BYREF|VT_UI4. int FAR * pintVal; // VT_BYREF|VT_INT. unsigned int FAR * puintVal; //VT_BYREF|VT_UINT. - _variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
使用时需加上#include <comdef.h>
例如:
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;
六、其它一些COM数据类型
- 根据ProgID得到CLSID
HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
CLSID clsid;
CLSIDFromProgID( L"MAPI.Folder",&clsid); - 根据CLSID得到ProgID
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
LPOLESTR pProgID = 0;
ProgIDFromCLSID( CLSID_IApplication,&pProgID);
...///可以使用pProgID
CoTaskMemFree(pProgID);//不要忘记释放
七、ANSI与Unicode
Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。
- 将ANSI转换到Unicode
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
(2)通过MultiByteToWideChar函数实现转换,例如:
char *szProgID = "MAPI.Folder";
WCHAR szWideProgID[128];
CLSID clsid;
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
szWideProgID[lLen] = '/0';
(3)通过A2W宏来实现,例如:
USES_CONVERSION;
CLSIDFromProgID( A2W(szProgID),&clsid); - 将Unicode转换到ANSI
(1)使用WideCharToMultiByte,例如:
// 假设已经有了一个Unicode 串 wszSomeString...
char szANSIString [MAX_PATH];
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
(2)使用W2A宏来实现,例如:
USES_CONVERSION;
pTemp=W2A(wszSomeString);
八、其它
- 对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam);///取低16位
WORD hiValue = HIWORD(lParam);///取高16位 - 对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue);///取低8位
BYTE hiValue = HIBYTE(wValue);///取高8位 - 两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
LONG MAKELONG( WORD wLow, WORD wHigh );
WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
LRESULT MAKELRESULT( WORD wLow, WORD wHigh ); - 两个8位的数据(BYTE)合成16位的数据(WORD)
WORD MAKEWORD( BYTE bLow, BYTE bHigh ); - 从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
例如COLORREF bkcolor = RGB(0x22,0x98,0x34); - 从COLORREF类型的颜色值得到RGB三个颜色值
BYTE Red = GetRValue(bkcolor); ///得到红颜色
BYTE Green = GetGValue(bkcolor); ///得到绿颜色
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色
九、注意事项
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )
后记:本文匆匆写成,错误之处在所难免,欢迎指正.
关于把BSTR类型数据转换成CString 类型数据时的问题?
当我在把BSTR类型数据转换成CString 或 “char* 类型”数据时,发现在BSTR类型字符串较短的情况下没问题,当较长时就会出现
内存读写错了。(在NT,2000下都测试是这样的。)
根据你所说:
1)字符串指针(char *)等已经被CString构造函数支持的数据类型 可以直接赋值 str = username;
2)当b 为BSTR类型时可以使用
char *p=_com_util::ConvertBSTRToString(b);
于是以下是对的:
CString cstr;
BSTR bstr;
....
cstr=com_util::ConvertBSTRToString(bstr);
...
可是当bstr非常大时(其实,较大时就会)就会出现内存读写错,不知何故。
此外我发现cstr=com_util::ConvertBSTRToString(bstr);
可以简化为 cstr=bstr; 但当bstr较大时同样出现这个问题。
请兄弟帮忙!急。谢谢!
如何转化((list*)fileip.bian)->liang
关于把CString转化成LPCTSTR的问题 作者:jakiesun 发表日期:2001-9-5 20:08:48
我记的我以前写过这样一段代码
void function()
{
CString str,str1,str2;
function((char*)(LPCTSTR)str1);
str=str1;
...//调试道此发现str2的值随着str的改变而改变,请问能解释一下为什么,如有回答,请通知
wangshaohong@sohu.com,tx先
}
添加lib支持 作者:磨刀霍霍 发表日期:2001-9-10 11:32:12
如果不添加会产生错误,在setting中加入comsupp.lib或者直接#pragma comment( lib, "comsupp.lib" )
微软认为缺省的设置call convention如果不设置成__cdecl也会出现同样的错误。
1。int 转成cstring ??
回复人: caigzhi(caigzhi) (2001-10-17 11:27:35) 得0分
CString 的成员函数Format()
int a = 2131;
CString str;
str.Format("%d",a);
回复人: tenchi(C与C++之间) (2001-10-17 11:32:12) 得0分
int i=2001;
char str[10];
_itoa(i,str,10);
CString szString=str;
回复人: fiolin(幽深的水) (2001-10-17 11:45:40) 得0分
他们两个的都可以!!
回复人: sohucsdnvc(thanks) (2001-10-17 13:24:17) 得0分
那如何把double转成cstring
回复人: yihugang(小虎子) (2001-10-17 13:29:15) 得6分
int i = 2131;
char *c=new char[20];
CString str;
sprintf(c,'%d',i);
str=*c;
回复人: Gu_c_h(Gu) (2001-10-17 14:07:17) 得0分
用 _gcvt 下面是 msdn 的例子
Example
/* _GCVT.C: This program converts -3.1415e5
* to its string representation.
*/
#include <stdlib.h>
#include <stdio.h>
void main( void )
{
char buffer[50];
double source = -3.1415e5;
_gcvt( source, 7, buffer );
printf( "source: %f buffer: '%s'/n", source, buffer );
_gcvt( source, 7, buffer );
printf( "source: %e buffer: '%s'/n", source, buffer );
}
Output
source: -314150.000000 buffer: '-314150.'
source: -3.141500e+005 buffer: '-314150.'
回复人: Gu_c_h(Gu) (2001-10-17 14:49:56) 得6分
int a = -3.1415e5;
CString str;
str.Format("%f",a);
回复人: ruixp(锐剑) (2001-10-17 15:06:48) 得6分
CString 的成员函数Format()
int a = 2131;
CString str;
str.Format("%d",a);
2。基类对象怎么能转换成派生类对象?
int CDaoListView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
lpCreateStruct->style |= LVS_REPORT |LVS_EDITLABELS;
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
创建ImageList;
CDaoViewApp * pApp = (CDaoViewApp *) AfxGetApp();
m_pImageList = new CImageList();
ASSERT(m_pImageList !=NULL);
m_pImageList->Create(16,16,TRUE,4,4);
m_pImageList->Add(pApp->LoadIcon(IDI_KEY));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON4));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON5));
CListCtrlEx& ctlList = (CListCtrlEx&) GetListCtrl();//我不懂的就这句,cListCtrlEx看下面的声明。
ctlList.SetImageList (m_pImageList, LVSIL_SMALL) ;
return 0;
}
class CListCtrlEx : public CListCtrl//类cListCtrlEx定义。
{.....
}
class CDaoListView : public CListView//cDaoListView定义!
{
...
}
注:我的问题是GetListCtrl()返回的是一个cListCtrl对象的引用,怎么能把它转换成一个它的派生类对象的引用?c++的类型转换怎么支持?
回复贴子:
回复人: lhj(努力加油) (2002-1-29 18:56:06) 得0分
CListCtrlEx& ctlList = (CListCtrlEx&) GetListCtrl();
这是强制类型转换,&表示是一个引用,lctList的值在这次赋值后不能被修改。
回复人: wwwsq(wwwsq) (2002-1-29 19:09:22) 得0分
建议你找本C++方面的书看看,VC虽然号称可视,实际上C++基础还是很重要的。
回复人: xcopy(xcopy) (2002-1-29 19:26:16) 得0分
用dynamic_cast()可以安全的转换。
3。如何在CString和double之间转换?要求转换之后能保留小数点,保留正负号??
cstring::format(%.xe) x为精度位
回复人: pchaos(杂讲) (2002-1-28 11:21:46) 得0分
CString str;
double db;
str = "123.456";
db = atof((LPCTSTR)str);
回复人: hgw111(hg) (2002-1-28 11:52:57) 得0分
CString -> double : atof
double ->CString :Format
回复人: pchaos(杂讲) (2002-1-28 13:46:04) 得0分
CString str;
double db;
str = "123.456";
db = atof((LPCTSTR)str);
db = 777.999;
str.format("%e", db);
4。字符型要转换成int??
atoi(str)
5。_bstr_t 到 unsigned int??
_bstr_t str;
unsigned int Length=6;
Length=Length-str.length();
6。VARIANT类型转换问题?
我在使用MSCOMM中SetOutput()函数时
形参必须为VARIANT变量
如何将其它的数据类型转换为VARIANT类型?
如:Cstring->VARIANT、 *char->VARIANT
我对VARIANT的类型结构体不太熟,请讲详细些(最好有范例),谢谢!
回复贴子:
回复人: vc_xiaoxin(小新) (2001-12-26 15:43:57) 得0分
VARIANT本身是一个复杂的结构,别的数据怎么转呀?关注
回复人: mpg_liu(星仁) (2001-12-27 18:33:50) 得10分
定义一个VARIANT变量后,他应该是一个结构体变量,其中有一个成员是字符型的,给这个成员赋值
回复人: LLnju(LLnju) (2001-12-27 18:36:10) 得0分
实在不清楚嘛就用 _variant_t , COleVariant 这些东东嘛,很好用的啊
回复人: softarts(CDMA2000) (2001-12-27 18:41:32) 得10分
构造一个就行了。
VARIANT varXX;
CString strYY;
varXX.vt=VT_BSTR;
varXX.bstrVal = strYY.allocsysstring();
应该可以了。
回复人: softarts(CDMA2000) (2001-12-27 18:42:11) 得0分
我也觉得COleVariant要好用一些,呵呵,我都用它。
回复人: bobofu(有问题要问) (2001-12-27 19:32:18) 得10分
CString str;
_variant_t var;
var = _variant_t(str);
7。COleVarant 如何转换为 CString?
CString 如何转换为 char *
CString 如何转换为 char[xx] ??
CString 如何转换为 char * wsprintf或者=
CString 如何转换为 char[xx] strcpy()
回复人: SecretGarden(天堂鸟) (2002-1-14 11:55:23) 得0分
COleVarant封装了VAREANT类型。
VAREANT类型其实是个巨大地Union,里面自然有你
想要地unsigned char *类型。
CString地GetBuffer和Format可以实现你的后两个问题
8。v_variant_t类型转换成cstring
总提示我cstring未定义
程序如下
_variant_t vfirstname;//存储的是数据库中的数据
CString str;//提示出错
vfirstname=pRs->GetCollect (_variant_t("Phone_Num"));
vfirstname.ChangeType (VT_BSTR);
str=vfirstname.bstrVal;//提示出错
回复贴子:
回复人: hydnoahark(诺亚方舟) (2001-11-12 11:56:51) 得10分
>>CString str;//提示出错
要求include <afx.h>并且设置Use run-time Library为Multithreaded
回复人: zhengyun_ustc(^-^) (2001-11-12 12:04:39) 得15分
CString未定义,说明你的工程没有引用MFC!!
要想使你的工程支持MFC,请按照以下步骤作:
1:在你的stdafx.h的头文件中加入:
#include "afxtempl.h"
这是一个囊括了MFC的集合定义的头文件,有了它,你的工程就识别Cstring类了。
2:在你的工程设置中,在General页中,选择“MFC”为“Using MFC in a shared DLL”
OK,现在再编译你的工程即可。
回复人: zhengyun_ustc(^-^) (2001-11-12 12:06:56) 得5分
_variant_t的bstrVal成员是BSTR类型。
它是一个指向一个OLECHART*的指针。
回复人: vickowang(小苍) (2001-11-12 12:48:21) 得5分
(char *)_bstr_t(vfirstname)
回复人: smallfool(smallfool) (2001-11-12 13:52:54) 得4分
或许你还需要一个从UNICODE字符到ANSI字符的转变函数
回复人: sun_1112(萧) (2001-11-12 17:34:44) 得0分
谢谢大家
给我这么大的支持!:)
回复人: zhengyun_ustc(^-^) (2001-11-14 13:24:07) 得0分
用vickowang(小苍)的意见可能会有问题,转换出的字符串应该是乱码。
因为(char *)转换需要一个const的字符串资源,才能强制转换。
所以应该:
_bstr_t bstrTemp = _bstr_t(vfirstname.bstrVal);
TCHAR szTemp[MAX_PATH];
szTemp = (char*)bstrTemp;
9。char * 转换为TCHAR类型??
直接转换,TCHAR相当于char了
char * s;
TCHAR * s1=(TCHAR *)s;
回复人: dysxq() (2001-12-21 21:26:25) 得0分
要看你的程序设置是ANSI还是UNICODE, 如果是ANSI,直接转,如果是UNICODE,TCHAR相当于WCHAR, 要用mbstowcsz转一下
回复人: xiaoxiaohan(萧晓寒) (2001-12-21 23:52:17) 得0分
Unicode :宽字节字符集
1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数?
可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。
调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。
2. 如何对DBCS(双字节字符集)字符串进行操作?
函数 描述
PTSTR CharNext ( LPCTSTR ); 返回字符串中下一个字符的地址
PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一个字符的地址
BOOL IsDBCSLeadByte( BYTE ); 如果该字节是DBCS字符的第一个字节,则返回非0值
3. 为什么要使用Unicode?
(1) 可以很容易地在不同语言之间进行数据交换。
(2) 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。
(3) 提高应用程序的运行效率。
Windows 2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那么系统首先要将字符串转换成
Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结
果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序
更加有效地运行。
Windows CE 本身就是使用Unicode的一种操作系统,完全不支持ANSI Windows函数
Windows 98 只支持ANSI,只能为ANSI开发应用程序。
Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。
4. 如何编写Unicode源代码?
Microsoft公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。实际上,可以编写单个源代码文件,以便使用或者不使用
Unicode来对它进行编译。只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。
_UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。
5. Windows定义的Unicode数据类型有哪些?
数据类型 说明
WCHAR Unicode字符
PWSTR 指向Unicode字符串的指针
PCWSTR 指向一个恒定的Unicode字符串的指针
对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。
ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。
6. 如何对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
7. 如何表示Unicode字符串常量?
字符集 实例
ANSI “string”
Unicode L“string”
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }
8. 为什么应当尽量使用操作系统函数?
这将有助于稍稍提高应用程序的运行性能,因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程Explorer.exe所使用。由于
这些函数使用得很多,因此,在应用程序运行时,它们可能已经被装入RAM。
如:StrCat,StrChr,StrCmp和StrCpy等。
9. 如何编写符合ANSI和Unicode的应用程序?
(1) 将文本串视为字符数组,而不是chars数组或字节数组。
(2) 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
(3) 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
(4) 将TEXT宏用于原义字符和字符串。
(5) 执行全局性替换(例如用PTSTR替换PSTR)。
(6) 修改字符串运算问题。例如函数通常希望在字符中传递一个缓存的大小,而不是字节。这意味着不应该传递sizeof(szBuffer),而应该传
递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来
分配内存。这就是说,应该调用malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。
10. 如何对字符串进行有选择的比较?
通过调用CompareString来实现。
标志 含义
NORM_IGNORECASE 忽略字母的大小写
NORM_IGNOREKANATYPE 不区分平假名与片假名字符
NORM_IGNORENONSPACE 忽略无间隔字符
NORM_IGNORESYMBOLS 忽略符号
NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字符
SORT_STRINGSORT 将标点符号作为普通符号来处理
11. 如何判断一个文本文件是ANSI还是Unicode?
判断如果文本文件的开头两个字节是0xFF和0xFE,那么就是Unicode,否则是ANSI。
12. 如何判断一段字符串是ANSI还是Unicode?
用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此
IsTextUnicode有可能返回不正确的结果。
13. 如何在Unicode与ANSI之间转换字符串?
Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。
回复人: xtky_limi(痛在心中笑在脸上) (2001-12-22 0:35:58) 得0分
上面说的已经比较全了。
回复人: xtky_limi(痛在心中笑在脸上) (2001-12-22 0:38:13) 得0分
TEXT是宏
相当于L##
它可以根据编译环境确定为DBMS,还是UNICODE字符集
10。int类型转换为CString类型?
回复人: tjmxf(天涯) (2001-12-17 19:59:34) 得0分
itoa()
回复人: zf925(天下哪来那么多高手) (2001-12-17 20:00:30) 得22分
char m[20];
str=str + itoa(i,m,10);
回复人: yuezifeng(wybzd) (2001-12-17 20:00:50) 得22分
CString str;
str.Format("%d",i);
回复人: kingfish(今飞) (2001-12-17 20:06:27) 得0分
str.Format("%s%d",str,i);
回复人: tanyajun(谈子) (2001-12-17 20:09:25) 得0分
CString str="test";
int i=11;
CString str1;
str1.Format("%d",i);
str = str+str1;
回复人: guanjinke(纶巾客) (2001-12-17 20:10:42) 得0分
int i=11;
CString str="test";
CString addition;
addition.Format("%d",i);
str+=addition;
就可以了。
11。关于sprintf类型转换的问题
sprintf(buf,"select price from ls01 where p_date>='%'",t_date)
其中t_date是CTime类型,%后面应该是什么呢?%s是String类型,%c是char,那么CTime型对应的是什么呢?
回复人: yakai(日落长河) (2001-12-17 17:45:47) 得0分
sprintf(buf,"select price from ls01 where p_date>='%S'",(LPCSTR)t_date.Format( "%A, %B %d, %Y" ));
如果不行,就
char temp[50];
CString str=t_date.Format( "%A, %B %d, %Y" );
strcpy(temp,(LPCSTR)str);
sprintf(buf,"select price from ls01 where p_date>='%S'",temp);
CTime::Format返回CString
回复人: loh(乐啸天涯) (2001-12-17 17:52:57) 得0分
wait
don't know
回复人: masterz() (2001-12-17 20:21:05) 得0分
SQL语句中日期要写成字符串"yyyymmdd"
12。类型转换 unsigned int <==>CString??
回复次数:8
发表时间:2001-12-17 10:25:23
unsigned int f;//unsigned int 0~4294967295
CString g;
f=2300000000;
g.Format("%d",f);
AfxMessageBox(g);
出错。
回复人: ydogg(灰毛兔频频) (2001-12-17 10:31:29) 得0分
unsigned int f;//unsigned int 0~4294967295
CString g;
f=2300000000;
g.Format("%d",f);
MessageBox(g);//使用AfxMessageBox,需要窗口的句炳参数
回复人: asdmusic8(asdmusic8) (2001-12-17 10:35:15) 得0分
我 AfxMessageBox(g); 和MessageBox(g); 都不错。
错的是g.从 2300000000=》1994967296
回复人: asdmusic8(asdmusic8) (2001-12-17 10:36:10) 得0分
是2300000000=》-1994967296 类型转换错。
回复人: ydogg(灰毛兔频频) (2001-12-17 10:37:54) 得6分
g.Format("%u",f);
回复人: asdmusic8(asdmusic8) (2001-12-17 10:40:24) 得0分
to dgsnmpoperate 那怎么从 CString ==>>unsigned int
回复人: kingfish(今飞) (2001-12-17 10:42:10) 得6分
既然是 unsigned int,
超过 0x7f000000 (2130706432) 当然不能用 %d (signed int)用%u
回复人: kingfish(今飞) (2001-12-17 10:44:57) 得8分
CString ==>>unsigned int
char *p = (LPSTR)(LPCSTR) g;
f = atoi(p);
13。static_cast、dynamic_cast 和直接类型转换(如 (void *)p )的区别?
发表时间:2001-12-14 9:31:13
先拷贝MSDN中的一小段话:
class B { ... };
class C : public B { ... };
class D : public C { ... };
void f(D* pd)
{
C* pc = dynamic_cast<C*>(pd); // ok: C is a direct base class
// pc points to C subobject of pd
B* pb = dynamic_cast<B*>(pd); // ok: B is an indirect base class
// pb points to B subobject of pd
...
}
我已经知道 static_cast 和 dynamic_cast 的作用,但MSDN中并没有提到这两个操作符与直接类型转换如
void f(D* pd)
{
C* pc = (C*)(pd);
B* pb = (B*)(pd);
...
}
的不同啊。不知道那位知道的告诉一声,在此不胜感谢,50分奉上。
回复贴子:ysdesigned(清泉) (2001-12-14 10:03:07) 得0分
static_cast、dynamic_cast 代 替 简 单 的 强 制 转 化, 从 而 消 除 多 继 承 带 来 的 歧 义。 使 用 这 两 个 运 算 符 号, 我 们可以 在 对 象 运 行 过 程 中 获 取 对 象 的 类 型 信 息
dynamic_cast 用于多态类型的转换
static_cast 用于非多态类型的转换
回复人: masterz() (2001-12-14 10:05:48) 得0分
static_cast<...>compile时能发现不正确的指针类型转换
dynamic_cast<...>运行时如果发现是不正确的指针类型转换会返回NULL
(void*)强制转换,如果是不正确的指针类型转换,没有办法检查,不如上面2中安全
回复人: meady() (2001-12-14 11:29:05) 得0分
类型安全
回复人: bluecrest(为什么我的VC还是那么的菜) (2001-12-14 11:45:34) 得0分
com技术内幕介绍过
我刚看完就忘了
14。byte数据类型转换成int型??
我用byte型读进一组数据想把他转成int型进行运算如何做呢?
如果再把int型转回byte又怎么实现呢?
回复人: louifox(兰陵笑笑生) (2001-12-6 9:18:38) 得0分
用下面这些宏:
WORD MAKEWORD(
BYTE bLow,
BYTE bHigh
);
BYTE LOBYTE(
WORD wValue
);
BYTE HIBYTE(
WORD wValue
);
回复人: chskim(大刀阔斧) (2001-12-6 9:21:04) 得0分
int i;
BYTE b;
b=128;
i=(int)b;
回复人: nannet(似的) (2001-12-6 9:38:24) 得0分
这个宏怎么用呀?有没有简单一点儿的,我现在能把BYTE 转成INT 型了,再转回去直接赋值可以吗?
回复人: louifox(兰陵笑笑生) (2001-12-6 9:46:24) 得20分
WORD wa;
BYTE ba=32,bb=64;
wa=MAKEWORD(ba,bb);
...
WORD wa=1234;
BYTE ba,bb;
ba=LOBYTE(wa);
bb=LOBYTE(wa);
回复人: nannet(似的) (2001-12-6 9:54:55) 得0分
问题解决了,多谢各位
15。类型转换的问题,unsigned int --> lptstr/lpctstr??
发表时间:2001-8-7 23:49:41
如果强制转换的话,会出现致命错误,有什么好的办法呢?
能列举一些其他的办法吗?
谢谢大虾!
回复人: AlphaOne(总是第一个倒下) (2001-8-8 0:02:43) 得5分
你为什么要强行转换呢?
如果你是要把int 的值作为 lptstr/lpctstr 的内容的话,
可以用CString:
unsigned int a = 100;
LPCTSTR lpText;
CString str;
str.Format("%d",a);
lpText = (LPCTSTR)str;
回复人: tryibest(编の魂) (2001-8-8 8:20:20) 得5分
wsprintf(str,"%u",ui);
回复人: zzh() (2001-8-8 9:04:39) 得5分
这种情况不需要进行强制转换,直接使用wsprintf就可以了。
回复人: GJA106(中文字符) (2001-8-8 10:10:51) 得5分
unsigned int m_na=22;
LPTSTR lptstr;
wsprintf(lptstr,"%u",m_na);
16。关于COM类型转换问题??
我定义了两个变量,一个是void *piaRef=new unsigned char[1000];另一个是m_Temp=new CComVariant();我的问题是如何将piaRef中的值
COPY到m_Temp中。
回复人: nichang() (2001-11-21 15:34:04) 得0分
CComBSTR bsRef=piaRef;
m_Temp=bsRef.copy()
回复人: VincentChin(瘟神) (2001-11-21 17:04:24) 得0分
CComBSTR bsRef=piaRef;
//error C2440: 'initializing' : cannot convert from 'void *' to 'class ATL::CComBSTR'
m_Temp=bsRef.copy();
//error C2440: '=' : cannot convert from 'unsigned short *' to 'class ATL::CComVariant *'
回复人: nichang() (2001-11-21 17:14:28) 得0分
将void*改为unsigned char *
回复人: VincentChin(瘟神) (2001-11-21 17:22:22) 得0分
我用CComBSTR bsRef=(unsigned char*)piaRef,也不行吗?
回复人: VincentChin(瘟神) (2001-11-21 17:28:06) 得0分
会报错:
error C2440: 'type cast' : cannot convert from 'unsigned char *' to 'class ATL::CComBSTR'
回复人: nichang() (2001-11-22 9:12:14) 得0分
m_Temp=::SysAllocString((OLECHAR *)piaRef)
回复人: VincentChin(瘟神) (2001-11-22 10:43:07) 得0分
//error C2440: '=' : cannot convert from 'unsigned short *' to 'class ATL::CComVariant *'
回复人: VincentChin(瘟神) (2001-11-22 11:22:35) 得0分
m_Temp=new CComVariant(::SysAllocString(OLECHAR *)piaRef));没有出错,但是我的m_Temp是COM组件中的一个PROPERTY,我想返回的是
unsigned char类型(单字节),但经过上述转换后,就不再是单字节了呀!怎么办?
回复人: jiangsheng(蒋晟) (2001-11-22 11:36:58) 得0分
把这个属性的类型改成BSTR
回复人: GrayWhite(灰白) (2001-11-22 12:01:09) 得0分
m_Temp = new CComVariant((char*) piaRef);就可以了。VB就是用的BSTR,你要给谁用阿?VC不用VARIANT的。
回复人: GrayWhite(灰白) (2001-11-22 12:18:18) 得19分
哦,我明白了,你要各字节数组:
SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, 1000);
if (!psa)
_com_issue_error(ERROR_NOT_ENOUGH_MEMORY);
HRESULT hr
for (long i = 0; i < 2; i ++)
{
if (FAILED (hr = SafeArrayPutElement(psa, &i, piaRef + i)))
_com_issue_error(hr);
}
_variant_t va; // include <comdef.h>
va.vt = VT_ARRAY | VT_UI1;
va.parray = psa;
m_Temp = new CComVariant(va);
回复人: VincentChin(瘟神) (2001-11-22 14:21:08) 得0分
SafeArrayPutElement(psa, &i, piaRef + i)
//error C2036: 'void *' : unknown size
回复人: VincentChin(瘟神) (2001-11-22 14:46:05) 得0分
To GrayWhite:为什么要for(long i=0;i<2;i++)?
回复人: nichang() (2001-11-22 15:16:35) 得0分
到底你想怎样转换嘛,是将数组内的值拷贝到CComVariant中存为字符串吗?
回复人: VincentChin(瘟神) (2001-11-22 15:28:35) 得0分
我是想把piaRef中的值照原样返回给其它程序使用。我正在做的是一个COM组件。谢谢各位!
回复人: nichang() (2001-11-22 15:34:40) 得10分
unsigned char *s=new unsigned char[1000];
strcpy((char*)s,"1234");//可以用你自己方法设置s中的值。
BSTR bstrS;
oleS=A2WBSTR((char*)s);//将char*转换成BSTR类型
CComVariant comVT;
comVT=oleS;//将BSTR转成CComVariant,这里一步也可,comVT=A2WBSTR((char*)s);
回复人: VincentChin(瘟神) (2001-11-22 16:54:07) 得0分
谢谢你!
但我还有一个问题,就是如果在s中有'/0'之类的东西我该怎么返回呢?char *遇到'/0'会认为到头了。完整的设计是这样的,我定义一个void * 用来从一个外部设备获取数据,该数据应该是unsigned char,我想把这个返回的数据作为属性传出,让其它应用使用(如VB)。
回复人: nichang() (2001-11-22 17:18:09) 得0分
将'/0'转换成其它如'/1'就OK了,
回复人: jiangsheng(蒋晟) (2001-11-22 18:07:16) 得0分
用字符串数组
回复人: VincentChin(瘟神) (2001-11-23 15:54:39) 得0分
谢谢各位的回复!我的问题解决了!如下:
SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, 1000);
if (!psa)
return S_FALSE;
HRESULT hr;
for (long i = 0; i < 1000; i ++)
if (FAILED (hr = SafeArrayPutElement(psa, &i, ((unsigned char*)piaRefTemplate) + i)))
return S_FALSE;
VARIANT va;
va.vt = VT_ARRAY | VT_UI1;
va.parray = psa;
CComVariant *m_Temp = new CComVariant();
m_Temp->Copy(&va);
17。类型转换 static_cast reinterprete_cast 的区别??
static_cast reinterprete_cast 的区别
回复人: tar(GPS) (2001-11-21 10:06:41) 得0分
static_cast会检查转换类型健的相关性
如果没有的画会有编译错误
reinterprete_cast就是硬转了
回复人: tigerwoods(tao) (2001-11-21 12:28:19) 得0分
是否可以这样理解:在多重继承中,static_cast可实现对象指针的移动,从而指向正确的父类对象部分,而reinterprete_cast不作偏移?
回复人: liu_feng_fly(我恨死驱动程序了,哎,就是为了混口饭吃) (2001-11-21 12:35:14) 得0分
在多重继承中可以用dynamic_cast啊
18。那如何取得CString中的字符串??
回复人: nichang() (2001-11-5 17:06:00) 得0分
=(LPCTSTR)CString变量
回复人: snake1122(领悟) (2001-11-5 17:12:16) 得0分
方法太多了:
GetAt,Left,Mid,Right等等,就看你怎么取了!
回复人: dusb(保时捷) (2001-11-5 17:34:29) 得0分
可是不管是GetAt,Left,Mid,Right返回类型都是CString,还是不能用,我是要取其中的字符串,奇怪的是,VC中没有string类型。(我要的字符串是给树型控件中的分支名称)
回复人: Alps_lou(云飞扬) (2001-11-5 17:41:36) 得0分
有string类型的啊,要包含<string>
回复人: luxes() (2001-11-5 17:42:19) 得0分
加上(LPCTSTR),相当于一个const char *了,还不能用?
回复人: wt007(tt) (2001-11-5 17:48:33) 得0分
GetBuffer
回复人: espon99() (2001-11-5 17:54:06) 得20分
(LPSTR)(LPCTSTR)
回复人: ineedyou(古寺僧) (2001-11-5 17:59:29) 得0分
...m_str.GetBuffer(needlen)...;
....
m_str.ReleaseBuffer()
回复人: dusb(保时捷) (2001-11-6 15:08:36) 得0分
espon99大侠,果然是绝招,不过能否解释一下啊?
19。如何从CString类型转换为Unicode string 类型?
回复人: ychener(贫血) (2001-10-20 10:28:48) 得0分
CString本身就支持Unicode的。
只要你选择的是UniCode编译,生成的可执行程序就是支持UniCode的
回复人: ychener(贫血) (2001-10-20 10:30:04) 得0分
CString类是自适应的就像TCHAR一样,如果你定义了UniCode宏 就会以UniCode编译
回复人: xjl1980_81(阿龙) (2001-10-20 10:35:16) 得0分
不是呀,我有个函数中有一个参数需Unicode string 类型的,比如应该填L"abc",而且引号中的内容要有变化,现在我有一个 temp变量,是CString类型的,如何用呀?
回复人: xt_jat(桑巴) (2001-10-20 10:39:37) 得0分
_T()
_TEXT()
行不行?
回复人: xjl1980_81(阿龙) (2001-10-20 10:43:18) 得0分
不行
回复人: Jeffery__Chen() (2001-10-20 11:04:53) 得0分
强制转化:
CString temp;
WCHAR wTemp = (WCHAR)temp;
回复人: xjl1980_81(阿龙) (2001-10-20 11:37:06) 得0分
to:Jeffery__Chen()
不对呀,出现不能转换的错误
回复人: hongzhh(关儿) (2001-10-20 11:39:42) 得0分
问题是这样的:
temp 是 CString类型变量,值为zhh
现在有一个API
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(
HCERTSTORE hCertStore,
DWORD dwCertEncodingType,
DWORD dwFindFlags,
DWORD dwFindType,
const void *pvFindPara, //此处用 L"zhh" 没问题
//请问怎么转换 可以 用temp
PCCERT_CONTEXT pPrevCertContext
);
在此谢谢大家,请帮忙看看
回复人: hongzhh(关儿) (2001-10-20 13:27:10) 得0分
WCHAR wszDomain[256];
MultiByteToWideChar( CP_ACP, 0, temp,
strlen(temp)+1, wszUserName,
sizeof(wszUserName)/sizeof(wszUserName[0]) );
wszUserName就是转换后的值
回复人: ychener(贫血) (2001-10-23 11:43:05) 得0分
只要你用的是CString的函数就行的,如果你要用类似strcpy函数时,看看MSDN中一般情况下都有响应的函数对于Unicode的。只要换成_tcscpy等等。
回复人: ychener(贫血) (2001-10-23 11:44:10) 得0分
你有没有定义Unicode宏?
20。请问在用ATL且不支持MFC的组件开发中,如何将从数据库中读到的DATE数据类型转换回为字符串??
复人: zhxuys(zhxuys) (2001-9-24 10:36:47) 得0分
ATL把datetime类型的列映射为DBTIMESTAMP类型,可取出该类型的year、month、day等,然后将这些数据传递回客户端,在客户端用CTime来构造
回复人: YUANXU(旭) (2001-9-24 11:18:14) 得0分
to zhxuys:CTime是MFC类,在ATL 不支持MFC时不能用。DATE其实质是个double*
回复人: zhxuys(zhxuys) (2001-9-24 11:57:01) 得0分
你在客户端与服务器端只用ATL规定的数据类型或VARIANT类型,而在客户端,可以用MFC来重新构造想要的数据结构
21。类型转换,CString to wchar_t ??
CString ss("aabb");
wchar_t* cc;
cc=ss.AllocSysString();
22。如何将CString类型转换为_bstr_t类型?
回复人: wei97081116(韦小宝) (2001-9-4 11:19:30) 得20分
CString b;
_bstr_t a;
a=(_bstr_t)b;
回复人: zhaozhen1212(赵振) (2001-9-18 1:30:18) 得0分
_bstr_t a=b.AllocSysString();;
23。如何把一个CString类型转换成一个普通的字符串,如char*?
回复人: liu_feng_fly(我恨死驱动程序了,哎,就是为了混口饭吃) (2001-9-17 18:00:52) 得0分
所以,直接用就可以,因为类里边有这样的转换函数
回复人: ydogg(灰毛兔频频) (2001-9-17 18:01:21) 得0分
CString show;
char *p = show.GetBuffer(show.GetLength());
回复人: jiangping_zhu(娜可露露之风之刃) (2001-9-17 18:02:05) 得0分
(char*)(LPCTSTR)str
回复人: bmouse(老鼠) (2001-9-18 0:10:56) 得0分
同意楼上!
回复人: bmouse(老鼠) (2001-9-18 0:13:22) 得0分
你还可以通过GetBuff来直接操作CString的缓冲区,不过要记着释放缓冲区.
24。CString 类型转换成 unsigned char类型吗??
回复人: LJN(*)风流倜傥无人及,玉树偏又临风立(*) (2001-9-17 12:46:01) 得0分
可以用CString.GetBuffer函数
回复人: xpmao() (2001-9-17 13:09:09) 得0分
CString strWork;
MessageBox(0,(LPSTR)strWork,0,0);
或MessageBox(0,strWork.GetBuffer(0),0,0);
回复人: sandd(降龙掌) (2001-9-17 13:17:32) 得0分
CString string;
(LPCTSTR)string;
回复人: jeff_hunter(PandaLee) (2001-9-17 13:45:30) 得0分
(unsigned char *)(LPCTSTR)
回复人: fandh(好了) (2001-9-17 14:00:57) 得0分
用(unsigned char *)(LPCTSTR)即可
回复人: ygd(ygd) (2001-9-17 16:11:17) 得0分
unsigned char *p;
CString str;
int length=str.GetLength();
for(int i=0;i<length;i++)
p[i]=str.GetAt(i);
回复人: swordbroken(断剑书生) (2001-9-17 16:25:57) 得0分
CString str;
unsigned char string[30];
strcpy(string,str);
25。何将一个unsigned int 类型变量值赋给类型为unsigned short的变量,并保证数值不丢失(当然数值在一定范围内)?
回复人: maxsuy(魔法师兔子) (2001-8-14 16:37:30) 得0分
直接=就OK了
回复人: oppmm(ppmm) (2001-8-14 16:38:11) 得0分
直接赋值
回复人: milefo(弥勒佛) (2001-8-14 16:40:40) 得0分
如果数值在一定范围内怎么回丢失呢?
unsigned short a;
unsigned int b;
a=( b & 0xffff);
你试试看吧!
26。CString ----char*
定义了char* aa的变量,现在有一个CString的变量bb,怎样把bb的值赋给aa呢?
回复人: emmai(WaTaXiWaWaTaXi) (2001-8-10 11:57:33) 得0分
aa=bb.GetBuffer();
回复人: hswqs(??????????????????) (2001-8-10 11:59:01) 得0分
aa= (LPSTR)(LPCTSTR)bb;
回复人: ydogg(灰毛兔) (2001-8-10 12:27:23) 得0分
1.aa=bb.GetBuffer(bb.GetLenth());//第一种方法
2.aa= (LPSTR)(LPCTSTR)bb; //第二种方法
回复人: zhizhi() (2001-8-10 13:16:23) 得0分
aa= (char *)(LPCTSTR)bb,hehe
27。在一个COM的接口函数中有一个 BSTR* 类型的参数,需要把一个 char * 类型转换为 BSTR* 类型,不知道如何转换? 由于调用这个函数后需要把这个参数值再取出来所以只能用指针,另外在调用的时候应该用什么类型的数据传递参数呢?大虾帮忙。
BSTR bstr = SysAllocString(L"字符串");
这样转换,用的时候你用地址操作符&啊,要不指针还得new
回复人: yongyue2000i(小吕) (2001-9-9 18:38:26) 得13分
CString str = "abcd";
BSTR bstr = str.AllocSysString();
回复人: houjzs() (2001-9-9 19:14:44) 得13分
BSTR b = SysAllocString(OLESTR("your string"));
28。要把一个double的数字输出到CEdit控件是否需要类型转换?
回复人: jiangsheng(蒋晟) (2001-8-24 14:46:17) 得0分
void AFXAPI DDX_Text( CDataExchange* pDX, int nIDC, double& value );
回复人: xiezhsh(雪中行) (2001-8-24 14:56:22) 得0分
假如你的CEdit相关的成员变量是Double型的,那根本用不着.(ClassWizard增加成员变量的对话框中,Variable Type选择Double可)
回复人: xiezhsh(雪中行) (2001-8-24 14:58:16) 得0分
假如你的CEdit相关的成员变量不是Double型的,是CString型,那就需要用ltoa()来转换成CString型,
回复人: haven(大天) (2001-8-24 14:58:32) 得0分
m_Edit.Fromat("%l",VarBouble);
updatedata(false);
回复人: 12345678() (2001-8-24 14:59:54) 得0分
CString m_Edit.Format("%lf", doubleVar);
GetDlgItem(EditID)->SetWindowText(m_strEdit);
29。该如何把 WINDOWPLACEMENT * 转换成 char **类型??
(char**)&pWP
30。怎样把CString的类型转换成char*型的?
回复人: dcz(dcz) (2001-8-19 19:13:27) 得5分
// str is CString var
char* temp = strdup(str);
...
free(temp);
回复人: yu900(疾风之狼) (2001-8-19 19:57:25) 得0分
getbuffer();即可!
回复人: aileen_long(挑战2001) (2001-8-19 21:10:35) 得0分
同意楼上的意见!
回复人: czh912() (2001-8-19 21:27:08) 得0分
char buf[20];
printf(buf,"%s",string);
回复人: casl(casl) (2001-8-19 22:59:44) 得5分
CString s("abc");
char* temp=s.GetBuffer(10);
...
s.ReleaseBuffer();
回复人: cocia(高亚) (2001-8-19 23:04:23) 得0分
char* temp=s.GetBuffer(10);
10是什么意思啊
回复人: kevin_dong(梦仙人) (2001-8-20 10:26:35) 得0分
// str is CString var
char* temp = strdup(str);
// free
free(temp);
我的这段代码在一个程序中能通过编译,但是在另外一个中总是出现cannot convert parameter 1 from 'class CString' to 'const char *'的错误。str和temp的类型都一样。这是为什么?
回复人: dcz(dcz) (2001-8-20 14:13:45) 得0分
you may setting your compiler option to UNICODE, in this case, declare the var:
// str is CString var
_TCHAR* temp = _tcsdup(str);
// free
free(str);
31。SA,SB为两个结构类型??
SA* A;
SB* B;
(SB*)A->...(调用函数)
请问此时A的类型,是指向SA还是SB
此时编译器是生成一个临时指针吗?
另外,
B=(SB*)A;此时A又是什么类型???
回复贴子:
回复人: ddeng(登登) (2001-8-9 17:13:58) 得0分
A的类型始终是SA *
B的类型始终是SB *
当进行强制类型转换时使的是临时指针
回复人: gold_water(风雨无阻) (2001-8-9 17:30:46) 得0分
同意楼上的。
32。char buff[100],char UserName[50][100],怎么将buff的值传给UserName,是其成为UserName数组中的某一项呢??
//0=<i<50
strcpy(UserName[i],buff);
回复人: Ashura(阿修罗) (2001-7-26 10:08:20) 得0分
呵呵,benbensan抢先一步。
回复人: tuita(斗牛士) (2001-7-26 10:13:22) 得0分
for (i=0;i<100;i++)
*(*(username+x)+i)=*(buffer+i)
其中0《X〈50
benbensan写的也对
回复人: kekeke(我是来向大家学习的) (2001-7-26 10:24:22) 得0分
那反过来呢?把UserName中的某一项读出赋值给buff呢?怎么弄?
回复人: benbensan(笨笨三) (2001-7-26 10:26:53) 得0分
//0=<i<50
strcpy(UserName[i],buff);
回复人: benbensan(笨笨三) (2001-7-26 10:28:15) 得0分
对不起,能错了,不过建议你看一下C语言了的指针和数组
//0=<i<50
strcpy(buff,UserName[i]);
回复人: jfzsl(剿匪总司令) (2001-7-26 10:32:57) 得0分
好好看看老潭的书先!OK?
回复人: kekeke(我是来向大家学习的) (2001-7-26 10:44:25) 得0分
好。。。。!
33。请问怎样把SYSTEMTIME类型转换成time_t类型?
SYSTEMTIME st;
GetLocalTime(&st);
CTime tm(st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
time_t t = tm.GetTime();
34。unsigned char Exponent[10]; //e
unsigned long eBytes; //e的字节数
如何转换成DWord型! ??
用强制类型转换呀
(DWord)eBeytes;
(DWord)Exponent[i];//(0<=i<=10);
回复人: xjl1980_81(阿龙) (2001-7-26 16:47:29) 得0分
我是说把e转换成DWORD型
也就是说把Exponent中的内容转换成DWORD型
回复人: cloudshadow1(云影) (2001-7-26 17:13:30) 得0分
用强制类型转换就可以了,(DWORD的高24位自动加0)
DWORD Des[10]
for (int i=0;i<11;i++)
Des[i]=Exponent[i];
至于那个ULONG的也是用强制类型软换就可以了
35。请问怎样把time_t类型转换成SYSTEMTIME类型?
回复人: haven(大天) (2001-7-26 17:12:36) 得0分
typedef struct _SYSTEMTIME
typedef long time_t
很明显不行嘛!
回复人: facexy(FACE仔) (2001-7-26 17:17:38) 得0分
哎呀,问错了,前后对象相反了;-(
忙昏了的结果…………
另外,TO 楼上的:
转换是可以的
struct tm *tblock;
SYSTEMTIME SystemTime;
memset(&SystemTime,0,sizeof(SYSTEMTIME));
tblock=localtime(&timer);
SystemTime.wYear=tblock->tm_year+1900;
SystemTime.wMonth=tblock->tm_mon+1;
SystemTime.wDay=tblock->tm_mday;
SystemTime.wHour=tblock->tm_hour;
SystemTime.wMinute=tblock->tm_min;
SystemTime.wSecond=tblock->tm_sec;
SystemTime.wDayOfWeek=tblock->tm_wday;
return &SystemTime;
回复人: zjh73(大章鱼) (2001-7-26 20:28:28) 得0分
有两种方法:
1、用CTime类
先用time_t类型构造一个CTime对象,再定义一个SYSTEMTIME结构,最后用CTime类的成员函数GetAsSystemTime将时间转换到SYSTEMTIME结构中
即可。
2、用gmtime函数
gmtime函数将time_t时间转换到tm结构中并返回一个tm指针,再将tm结构的相对应的项赋给SYSTEMTIME相对应的项即可,不过用这种方法要注
意这两种结构在天、星期等方面的记数方法有点区别,一个一般从0开始,一个一般从1开始,赋值时要注意校正,还有要注意的是SYSTEMTIME
结构中有一项是毫秒,而time_t是以秒记数的。
回复人: zjh73(大章鱼) (2001-7-26 20:32:13) 得0分
反过来也可以用Ctime类的方法
就是先用SYSTEMTIME结构构造一个CTime对象,在用CTime类中的成员函数GetTime返回一个对应的time_t即可。 36。我现在正在学习SDK编程,遇到的问题是:
我定义了一个静态长整形变量,
static long lScore=0;
我想把窗口的标题换成长整形数值,用SetWindowText函数来实现,
由于它的第二个参数要求数据类型为 unsigned short *,但用其来实现强制转换时
总是出现编译错误:
cannot convert parameter 2 from 'unsigned short *' to 'const char *'
后来改成来LPCTSTR 来实现强制转换,没有出现编译错误,但函数总是执行不成功,
请教各位高人,这倒底是怎么回事???
回复贴子:
回复人: prog_st(st) (2001-8-4 21:20:07) 得0分
/* ITOA.C: This program converts integers of various
* sizes to strings in various radixes.
*/
#include <stdlib.h>
#include <stdio.h>
void main( void )
{
char buffer[20];
int i = 3445;
long l = -344115L;
unsigned long ul = 1234567890UL;
_itoa( i, buffer, 10 );
printf( "String of integer %d (radix 10): %s/n", i, buffer );
_itoa( i, buffer, 16 );
printf( "String of integer %d (radix 16): 0x%s/n", i, buffer );
_itoa( i, buffer, 2 );
printf( "String of integer %d (radix 2): %s/n", i, buffer );
_ltoa( l, buffer, 16 );
printf( "String of long int %ld (radix 16): 0x%s/n", l,
buffer );
_ultoa( ul, buffer, 16 );
printf( "String of unsigned long %lu (radix 16): 0x%s/n", ul,
buffer );
}
Output
String of integer 3445 (radix 10): 3445
String of integer 3445 (radix 16): 0xd75
String of integer 3445 (radix 2): 110101110101
String of long int -344115 (radix 16): 0xfffabfcd
String of unsigned long 1234567890 (radix 16): 0x499602d2
回复人: lwg7603(刑满释放人员) (2001-8-4 21:36:15) 得0分
TCHAR str[255]={_T('/0')};
_stprintf(str,_T("%d"),lScore);
SetWindowText(hwnd,str);
37。我用socket发送的的buf中间需要的是 char *类型的数据,我想将一个 struct 直接转换成 char * 发过去。
我用
struct ABCD *abcd;
char *buf;
abcd = (ABCD *)calloc(1,sizeof(ABCD));
buf = (char *)calloc(1,sizeof(ABCD));
///
给abcd 中间赋值,其中有多个char[]的值和int 的值
///
memcpy(buf,abcd,sizeof(ABCD));
//strcpy(buf,(char *)abcd);也不可以
sock(host,buf,....);
//sock(host,(char *)buf,...);也不可以
问题就是在这里,这个buf中间的值总是不对,大家知道为什么否。
回复人: wolf721() (2001-7-30 18:18:34) 得5分
你传的是个指针值,而不是数据
回复人: kiko_lee(到处瞧瞧) (2001-7-30 18:50:49) 得0分
但是用memcpy这个是将整个数据都复制过去
回复人: lz_0618(lz_0618) (2001-7-30 19:26:44) 得5分
你用的VC???改成ABCD *abcd;后编译一点问题也没有啊!
sock(host,buf,....);这不知是什么,自定义函数?
typedef struct _ABCD
{
int ID;
char Name[10];
}ABCD;
.......
ABCD *abcd;
char *buf;
abcd = (ABCD *)calloc(2,sizeof(ABCD));
buf = (char *)calloc(2,sizeof(ABCD));
///
//给abcd 中间赋值,其中有多个char[]的值和int 的值
abcd[0].ID =1;
abcd[1].ID =2;
///
memcpy(buf,abcd,2*sizeof(ABCD));
strcpy(buf,(char *)abcd);//也不可以
buf中的内容也正确!!
回复人: kiko_lee(到处瞧瞧) (2001-7-31 8:57:52) 得0分
我按照楼上的兄弟说的,做了一下,但是仍然做不下来,我用
memcpy(buf,abcd,sizeof(ABCD));
中间的abcd,不知道是不是地址的问题。
回复人: supersusheng(小苏) (2001-7-31 14:30:42) 得0分
老大,你sizeof()得出的数值事多大,看看吧。
回复人: ydogg(灰毛兔) (2001-7-31 14:41:52) 得0分
只能传递流数据,结构是传递不过去的。
回复人: IamNotMan(NorGirl) (2001-7-31 14:50:53) 得5分
我常这么用
ABCD a ;
//给a的各个域赋值(一定不能含有指针项)
char* buff = new char[sizeof(ABCD)];
memcpy(buff,&a,sizeof(ABCD));
//或者 *(ABCD*)buff = a;
.................
如果buff里的数对,说明问题不在这儿吧
回复人: zb_china(最后一座水车zb_china新浪) (2001-7-31 15:16:24) 得0分
看不明白
回复人: eggplant(拉拉) (2001-7-31 15:42:48) 得0分
最好使用memcpy(),因为struct中的值有可能包含零字节,所以strcpy()可能不对,如果传递struct,最好把struct的字节对齐改为以字节为单位。
回复人: lvfengxun(lfx) (2001-7-31 16:06:57) 得5分
直接将结构指针作为send的参数发就可以了,还用转换什么
有必要在这里讨论吗?
struct AA
{
int a;
char b[100];
};
struct AA aa;
aa.a=11;
strcpy(aa.b,"aaa");
send(hSocket,(char *)(&aa),sizeof(aa),0);
//OK
回复人: mydewang(mydewang) (2001-7-31 16:33:21) 得0分
其实这里是一个字节对齐的问题,
比如
struct AA
{
int a;
char b;
};
那么sizeof( struct AA )就不等于5了,而是8了,所以,将这个结构赋值给一个char *,里面会多出一些零...
需要解决这个问题,可以在Project->Setting->Link->Project Options里加上/Zp1
另外,可以参考一下MSDN里/Zp的编译选项.....
回复人: lz_0618(lz_0618) (2001-7-31 19:43:54) 得0分
根本不是什么字节对齐的问题,我上面的程序经过测试都好用啊,这位老兄用我的那段程序究竟是什么错误,能说清楚点吗???
我这边用socket发送结构是一点问题也没有啊,而且是在VC和Delphi编的程序间通讯,当然,这时应该注意字节对齐的问题了,在VC程序间,
只要不是故意将服务器和客户端的编译环境设的不一样,肯定是没有什么问题的,最多是多传几个Bit罢了。
回复人: kiko_lee(到处瞧瞧) (2001-8-3 11:02:51) 得0分
我发现将char * memcpy 到 char * 中间都有点问题,但是如果放到 char []中间就可以了,大家知道为什么否?
回复人: ydogg(灰毛兔) (2001-8-3 11:40:35) 得0分
memcpy不copy最后的'/0'...
回复人: wenjunlin2000(微软克星) (2001-8-3 14:32:17) 得0分
是你看错了
因为char*是以0 结尾的
回复人: mc_music(狂沙) (2001-8-3 15:07:21) 得0分
请注意我的程序:
struct ABCD *abcd;
char *buf;
abcd = (ABCD *)calloc(1,sizeof(ABCD));
//初始化abcd
buf=abcd;//指针直接符值就可以了
回复人: zhangnanonnet(WinSockZhang) (2001-8-3 16:21:03) 得0分
你试试把类型变为BYTE
回复人: kiko_lee(到处瞧瞧) (2001-8-7 9:21:08) 得0分
不管了,给分,大家都有不少的建议呢。
38。double dou=12.34;我如何可以得到char * ch="12.34";转换函数是什么?
回复人: wyzegg(蛋) (2001-7-24 21:26:04) 得50分
double dou=12.34;
char * ch;
ch=malloc(100);
sprintf(ch,"%5.2f",dou);
回复人: wyzegg(蛋) (2001-7-24 21:28:24) 得0分
或者
#include <stdlib.h>
#include <stdio.h>
void main( void )
{
int decimal, sign;
char *buffer;
int precision = 10;
double source = 3.1415926535;
buffer = _ecvt( source, precision, &decimal, &sign );
printf( "source: %2.10f buffer: '%s' decimal: %d sign: %d/n",
source, buffer, decimal, sign );
}
但是第一种常用
回复人: Matrix_w(学会一点点) (2001-7-24 21:32:43) 得30分
int decimal, sign;
double dou =12.34;
char* ch;
ch = _ecvt(dou,4,&decimal,&sign);
回复人: imhua(华弟) (2001-7-24 21:35:02) 得20分
double dou=12.34;
char *str;
gcvt(dou,5,str); //5是长度
MessageBox(str);
回复人: Matrix_w(学会一点点) (2001-7-24 21:37:58) 得0分
/* _GCVT.C: This program converts -3.1415e5
* to its string representation.
*/
#include <stdlib.h>
#include <stdio.h>
void main( void )
{
char buffer[50];
double source = -3.1415e5;
_gcvt( source, 7, buffer );
printf( "source: %f buffer: '%s'/n", source, buffer );
_gcvt( source, 7, buffer );
printf( "source: %e buffer: '%s'/n", source, buffer );
}
Output
source: -314150.000000 buffer: '-314150.'
source: -3.141500e+005 buffer: '-314150.'
39。 我在ADO中调用一个存储过程,存储过程有三个输入参数@useradd char(30),@username char(10),@userage char(3),现在要把char
*addr,char *name,char *age分别赋值给他们。??
我做了如下定义:
_ParameterPtr para1;
_variant_t var1,var2,var3;
==============================================================
var1.vt=VT_BSTR;
var1.bstrval=addr;/(编译错误)
==============================================================
para1=m_pCommand->CreateParameter(L"useradd",adBSTR,adParamInput,30,var1);
m_pCommand->Parameters->Append(para1);
编译结果出现下面错误:
cannot convert from 'char *' to 'unsigned short *
不知道类型是不是选择VT_BSTR?
回复人:tar(GPS) (2001-7-12 18:49:05) 得15分
var1.bstrval应该指向宽字符的字符串,
即unicode字符串
use _bstr_t to convert it
_bstr_t var1(addr);
回复人:happyhackwang() (2001-7-12 20:06:48) 得5分
char *要进行转换成BSTR
回复人:WhiteWaterBlueSky(疯狂数码) (2001-7-13 9:35:15) 得10分
SDK中是这样的
1。先用MultiByteToWideChar把char* 转为wchar_t*
2。再用SysAllocString把wchar_t*转为BSTR
回复人:tar(GPS) (2001-7-13 14:10:01) 得0分
faint,我都已经把语句写出来了
_bstr_t a(addr);
var1.vt=VT_BSTR;
var1.bstrval=(wchar_t *)a;
回复人:xwchena(西风之神) (2001-7-13 15:57:00) 得0分
大哥,我改完之后记录集无结果返回。我的代码是这样的:
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdStoredProc);
if(!m_pRecordset->adoEOF)
{
result1=m_pRecordset->GetCollect((long)0);
if(result1.vt!=NULL)
{
result1.ChangeType(VT_BSTR);
CString strResult1=result1.bstrVal;
strcpy(resval,strResult1);
}
调试的时候看到执行完m_pCommand->Execute()后m_pRecordset就到了记录集的尾部
而如果把char*型都改成int型,结果就能返回记录集。
这是为什么啊???
回复人:tar(GPS) (2001-7-13 19:19:51) 得0分
try adVarChar
回复人:xwchena(西风之神) (2001-7-13 22:54:21) 得0分
还是不行,记录集没有返回结果
回复人:seesi(不是我想骗你,是我不知道怎么才能不骗!) (2001-7-14 0:24:36)
40。如何将 BSTR pVal 赋给:unsigned char *pw;如何将:unsigned char digest[16]赋给 BSTR *pOutVal?
USES_CONVERSION;
*pOutVal=SysAllocString(A2W((LPTSTR)digest));
unsigned char *pw = (unsigned char *)_com_util::ConvertBSTRToString(pInVal);
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow