找回密码
 注册
查看: 4854|回复: 0

常用数据类型使用转换详解

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君
/ Y3 Q- Z! A- V- P5 G0 G5 F( k% n
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。
/ c) w0 S* A- D/ A" c9 i7 X, K) C3 _8 @9 J; z
我们先定义一些常见类型变量借以说明
& P5 T" P$ l& [6 ?0 F5 T: _" b+ R1 z" I% O% Z
int i = 100;
( B" v% e! X) E2 l0 `$ c5 along l = 2001;
& q5 z  A- r3 S5 o* Q- Kfloat f=300.2;/ F4 v( t$ D" X' o
double d=12345.119;
' a9 c  D& @2 ~  m7 [" o& f4 F" }5 xchar username[]="程佩君";
! T3 M' _( h; U$ E8 x6 X) p0 Tchar temp[200];% D- |3 ^4 n* U1 C) L
char *buf;
. m: r" G1 s- \+ M/ fCString str;
/ m+ F* f$ x; X* P& f: u1 o_variant_t v1;
. \& s: @1 Q. t_bstr_t v2;. ~+ I5 V' D  s
6 S  k& R0 z& X; L5 k# ~) a; r
一、其它数据类型转换为字符串
/ R6 K9 _; L& }7 u+ i! J$ q
4 X( w' `) G# a& m: \% i
( W6 ^! s9 V" U1 c短整型(int)
6 t2 Y% O/ O  R9 H/ P6 ]5 r  ^itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制% q& a: m4 z' I7 o) `- \; V+ J
itoa(i,temp,2); ///按二进制方式转换
6 O8 }* @4 t" o7 e: ]长整型(long)
: i9 {8 G; X$ E. F5 M# \2 Gltoa(l,temp,10);
2 f% F6 m: }7 A3 r8 v: S浮点数(float,double)
* ?9 W# P- J+ u+ s; L. E) _用fcvt可以完成转换,这是MSDN中的例子:. J& q: x: Z  v; C
int decimal, sign;
+ y/ f2 G! C  T, _/ m; c+ h5 |5 q% i9 fchar *buffer; $ X9 X# Y( b  X; ~3 X' ]7 ^
double source = 3.1415926535; # h$ X  i& I9 T* J' ^/ y
buffer = _fcvt( source, 7, &decimal, &sign ); 9 G7 {, P0 g  l. O; W
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
; i. D) T# |5 c% Cdecimal表示小数点的位置,sign表示符号:0为正数,1为负数
2 {( j( A( B( b' y1 h3 n5 sCString变量
7 m5 |0 N! w# ^! p: Mstr = "2008北京奥运";
7 |% ]" D7 r/ E% e3 Vbuf = (LPSTR)(LPCTSTR)str; " E0 ]3 W; `3 W6 x
BSTR变量# _; n& a, |. z/ W4 j
BSTR bstrValue = ::SysAllocString(L"程序员"); 6 B+ X* Z+ M( W+ F" X' h
char * buf = _com_util::ConvertBSTRToString(bstrValue); 9 H& ~' d: d$ i: Q7 u
SysFreeString(bstrValue);
8 V- r; L" t! P$ bAfxMessageBox(buf);
) v* z: O4 l% z4 b" A+ \delete(buf);
) ~9 k2 ^# |- v! P  w3 a$ YCComBSTR变量! @! r% A3 P2 [2 I. w: y
CComBSTR bstrVar("test"); # Z& D0 O4 Y' Y
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str); 3 d4 L( y/ Z- F/ K) U$ s% j
AfxMessageBox(buf);
2 g% a* f& T  p. l; {4 o& Adelete(buf); $ Y- r0 L$ k/ [3 {4 _' `1 l: v

; h! }2 {, }7 N* P+ m3 u* V_bstr_t变量( }! P8 N* L/ `6 t  R
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用: h& V) n+ k5 x6 I2 O' y
_bstr_t bstrVar("test");
8 Y4 c0 O& ?- s, a" s6 i) Fconst char *buf = bstrVar;///不要修改buf中的内容
5 q# X0 Q2 d1 M* @, z6 VAfxMessageBox(buf); 3 X  `, I4 R6 s& |3 }1 a6 l: _7 h' X

# q) r' t5 N& S1 R; I# m* W5 L( t6 h' x9 D1 ~. }; P
通用方法(针对非COM数据类型)5 b4 e1 ^/ T5 D/ k
用sprintf完成转换
# z5 Y2 c: ^9 k- U; ~char  buffer[200];5 h6 u5 i8 ^: f$ D, X& g9 O
char  c = '1';
( V* i8 H" E6 y8 rint   i = 35;$ _' v" I6 X( l% _( |+ S3 p- q
long  j = 1000;
" ]( J( j- U5 L# z0 _float f = 1.7320534f;* i+ F& f5 n4 Z% _& k% j
sprintf( buffer, "%c",c);
" p  n$ m' b  |- h: K/ Psprintf( buffer, "%d",i);0 H# r: F9 k+ {- Q
sprintf( buffer, "%d",j);
* X! U8 p+ M. u* fsprintf( buffer, "%f",f);
9 L0 b8 X, ~; v, Z: }6 O8 w- g( M0 i; T; f; I$ g4 A* l
二、字符串转换为其它数据类型
6 Y1 l6 g6 g$ @+ {4 Hstrcpy(temp,"123"); 4 {, C' e  R1 j
  T% _% N$ a4 T
短整型(int)* W; ]( P+ p3 u7 `3 ?
i = atoi(temp);
1 v: E8 e8 @/ i9 z! C% k/ c; R长整型(long)6 @8 c8 j8 v( B  }& ^. A
l = atol(temp); # M8 Y8 B( m. x1 Y
浮点(double)3 ?: E8 s, ]$ P6 w% }
d = atof(temp); . F) ?& }& k9 C5 n# l$ B
CString变量0 M+ j' x9 b& K4 ?3 F
CString name = temp;
  P7 Y2 e; g! j6 }" q* ABSTR变量 ) f2 I5 J6 s# R% v$ C
BSTR bstrValue = ::SysAllocString(L"程序员");
: i5 W& O% o/ g# e+ P$ O...///完成对bstrValue的使用
- g$ ~  H( S" z6 i& pSysFreeString(bstrValue); % E8 r& z: F* h2 h/ f) t! v
" I* Y* Y( m5 O+ \- ^
CComBSTR变量! @% \8 N7 V. o
CComBSTR类型变量可以直接赋值1 _" o, r9 m% l
CComBSTR bstrVar1("test");
( t, d( V& ^. i9 \CComBSTR bstrVar2(temp);8 ?5 Y" R  f  @7 W# U

. ~4 K0 G& @: [$ @* e_bstr_t变量
" l/ L6 }4 T# W. E* l+ I3 E_bstr_t类型的变量可以直接赋值
1 F3 z. y# \" w% H" ]_bstr_t bstrVar1("test");
7 Q, T8 v! I1 M( A1 M_bstr_t bstrVar2(temp); + b2 I' V. Q+ p
% u" u( h( I- s! v8 H! [+ ?* p

7 \6 e3 h' }* u6 c三、其它数据类型转换到CString+ k# t7 p* u+ ?5 `
使用CString的成员函数Format来转换,例如:- K8 D( D% U7 B5 q0 j

7 L0 ]* ~; U- F, Z6 w: c8 _2 T" c( f- b" V7 W
整数(int)
% g0 d  J. q- j0 z; ^+ Cstr.Format("%d",i); / c0 w5 \1 ?- B1 E8 E
浮点数(float)' p9 T9 B! X& U+ W4 T: A/ B
str.Format("%f",i); 0 \  {$ o3 H. q) n" ^9 F
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
) F6 ^4 S3 |% |str = username;
5 I# F" L! j: J; \对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
4 H0 o. I& r% ]* H, s3 h& T
5 T, c+ K, C% M. a- S四、BSTR、_bstr_t与CComBSTR2 p, k- J, p' W, q3 C! }1 `" _3 \/ f
8 _. ^1 h/ w( B; r9 |; m) s0 l6 ~" T

, O' ^0 E& T. h7 L  a$ [CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
* N  W! }% y7 ]! a1 [8 i+ Y+ Rchar *转换到BSTR可以这样:
) p- I) @2 U$ q+ i: fBSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
( \1 o3 F; M" A( R: ]SysFreeString(bstrValue); . Y% [5 T+ |2 C' m* a
反之可以使用
& x( e: ^+ n) }+ u% g/ d, F( kchar *p=_com_util::ConvertBSTRToString(b);. N, c4 v3 \7 o/ t3 n" Q6 T
delete p;
7 ]6 B% W3 A2 c( u! E2 O* a8 n具体可以参考一,二段落里的具体说明。
' V) X) e% v2 x7 T# E# t6 l
, L' O8 A8 a) Z7 M/ RCComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
: S/ _$ A! {, ^特别是_bstr_t,建议大家使用它。
8 S- z8 p' e9 b" v5 J8 s) w4 d" t9 |3 U. h

- [( F. f! I4 f5 o( h) b五、VARIANT 、_variant_t 与 COleVariant
' L8 h) I( z2 L' }: X) k# m- O! |) `8 j1 r* i
% R" n( U" V+ S# m  J" Q7 a' Y
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。% \7 w$ `* C% S4 \0 U7 |- J8 D
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:) M* j7 J2 a  B. c
VARIANT va;
" P4 T9 U" Y5 g( b+ u6 O8 sint a=2001;
/ X1 [4 V% m- m$ B3 Cva.vt=VT_I4;///指明整型数据
& G. o/ Y) X: h0 t$ nva.lVal=a; ///赋值1 W" D6 Z" G6 |" a- C6 E4 B
0 z8 `8 O% T: R0 [& y" Y+ }
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:  B) j0 g6 ]' x$ ~

5 {# ]+ V& x- zByte bVal;  // VT_UI1. ; h7 v0 `( L, a" X; ^  H
Short iVal;  // VT_I2.
+ Y1 _" i" b( q) ?) @7 olong lVal;  // VT_I4.
' X3 {/ {! S4 [6 X; {float fltVal;  // VT_R4. # a# D6 T5 ?* H, L1 J: X
double dblVal;  // VT_R8. 9 o7 I' I  B# o% D# _" h" Q
VARIANT_BOOL boolVal;  // VT_BOOL. / L+ d3 F  a* M3 }8 R- @2 j
SCODE scode;  // VT_ERROR.
& x& D. D* p8 g0 W! p% cCY cyVal;  // VT_CY.
! P3 `4 \1 t0 xDATE date;  // VT_DATE. 3 s, h3 S6 C7 k) k! V( A
BSTR bstrVal;  // VT_BSTR. " ^$ P) l( H& q. l
DECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. / N9 V$ u& x$ w! `, r0 M4 t
IUnknown FAR* punkVal;  // VT_UNKNOWN. 7 I) x0 y* s! K; }& U1 w# C
IDispatch FAR* pdispVal;  // VT_DISPATCH.
4 k( }& t! h2 N! g- GSAFEARRAY FAR* parray;  // VT_ARRAY|*.
0 ]% J  w" w* V% w8 NByte FAR* pbVal;  // VT_BYREF|VT_UI1. 5 g) _+ x9 q& M
short FAR* piVal;  // VT_BYREF|VT_I2. " b2 E4 j6 q6 Y$ j
long FAR* plVal;  // VT_BYREF|VT_I4.
. w# B6 j! ~1 q$ S# r# v, @float FAR* pfltVal;  // VT_BYREF|VT_R4. # [* K+ f9 o4 d/ I
double FAR* pdblVal;  // VT_BYREF|VT_R8.
0 {; [8 s; T0 t# p2 U3 }: }VARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL.
7 M. ?* l4 H. c$ ^! WSCODE FAR* pscode;  // VT_BYREF|VT_ERROR.
. E" S: `2 V+ h3 ~' aCY FAR* pcyVal;  // VT_BYREF|VT_CY. 5 Y! ~% A- g7 ~7 @% _
DATE FAR* pdate;  // VT_BYREF|VT_DATE.
- k6 f6 ?0 z& ^4 i5 L) m( M3 Z) fBSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR.
- g% R* w9 J- c; ?5 LIUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
& D. E' T4 K, m. f; B; z! kIDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
2 _; y# N' F3 O9 MSAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. 0 I7 S3 ~* T+ u* i
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT.
7 j% ?: H, N: {- ?) xvoid FAR* byref;  // Generic ByRef. ' Y) b- n1 ]! _5 }
char cVal;  // VT_I1. ! C5 D  v2 \/ ^* N0 W5 d
unsigned short uiVal;  // VT_UI2.
$ D5 h; `; q$ a- Lunsigned long ulVal;  // VT_UI4.
  B; g4 j/ N8 }; V" ^int intVal;  // VT_INT. 6 P6 D9 K$ i; M0 E9 J3 N" B
unsigned int uintVal;  // VT_UINT.
& L+ |  X; x  d. s& e) P3 F" Mchar FAR * pcVal;  // VT_BYREF|VT_I1.
! o  H% H" K  o' @3 nunsigned short FAR * puiVal;  // VT_BYREF|VT_UI2.
% Y. B* ~, J. runsigned long FAR * pulVal;  // VT_BYREF|VT_UI4.
' y7 r& j; o6 `, y9 R; S& o9 ^int FAR * pintVal;  // VT_BYREF|VT_INT.
5 y7 ^8 U  U3 M8 F) a" z  f6 Gunsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
. d* y" |$ x) @) k) [
+ M6 v5 Y7 m0 Z$ |2 ?- a- J" Z' }* J0 n8 ~# [) c' U  Q4 [" a
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
, j; _9 b: b! E& j' `使用时需加上#include <comdef.h>
" c) `1 k5 h  N例如:# O6 [# T4 P# c9 k4 X: i
long l=222;! b0 p: p, [2 S; b9 ]% B8 J
ing i=100;$ f4 T8 O4 g- u* _7 F/ l# x% w; M
_variant_t lVal(l);$ r, S& H: N1 J8 F! y
lVal = (long)i;' V8 _2 ]" f  }5 U7 P. f

- q# t# n6 _2 d8 Q
* l/ ~& N) L0 s! J' `COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
8 s" l) N3 |$ P' y) e8 jCOleVariant v3 = "字符串", v4 = (long)1999;
  p+ Z, G2 s- s4 V, Z) X# PCString str =(BSTR)v3.pbstrVal;7 o1 c) _# f! P
long i = v4.lVal;
5 I, U9 ~  q8 P4 B
9 [# c; V" q. {; y! Q0 X4 R0 M
( `- E1 `# R7 |, V" ?1 ?六、其它一些COM数据类型
: M9 ?3 h! M% e4 _1 ?- n$ h2 N6 @7 A
& @! N! \, e/ e6 I" _根据ProgID得到CLSID
  T+ T! R' ?+ h0 h1 l/ vHRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
0 \% ?. p! t0 O9 H% n" {CLSID clsid;
" e! V: Q7 c# _! QCLSIDFromProgID( L"MAPI.Folder",&clsid);% Z' _, o# W+ L

" g( n! d6 P1 d4 G% Y0 _+ q, s( x根据CLSID得到ProgID
$ U' k: e$ C8 b" oWINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
, i3 h- X  z4 D8 L例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
& Z% E% k3 U5 Y1 A1 OLPOLESTR pProgID = 0;2 w8 }+ w0 ?# G9 D: L* f# {5 e& j
ProgIDFromCLSID( CLSID_IApplication,&pProgID);
7 g/ V. }+ N& @: _# k7 J...///可以使用pProgID
7 P7 `* @" o' Z1 F; g# @: XCoTaskMemFree(pProgID);//不要忘记释放 & P1 W9 D. X) f( A/ z6 P

) V& @- h( i) b1 y. {* Y七、ANSI与Unicode* X1 q# p) B" w8 o" K6 ^8 e) i
Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。
- `) a2 R$ S/ z5 k# @0 u
/ Z- U; T$ u1 i0 b将ANSI转换到Unicode
. U9 S" x; C1 g0 o1 p9 p(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
+ s/ f; Z0 X. \1 n: `1 j6 Y/ K(2)通过MultiByteToWideChar函数实现转换,例如:
3 o  y. k9 `" z" n- Ochar *szProgID = "MAPI.Folder";4 c. n% ^  q) ^7 P' |
WCHAR szWideProgID[128];8 X( ]! E5 W* \( D8 N
CLSID clsid;
! U! j+ q( V  }+ {9 r5 S; Hlong lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));) j' N: a# m; F. Q. R" z; b+ k
szWideProgID[lLen] = '\0';
; X' _( V7 @! h(3)通过A2W宏来实现,例如:
1 e/ O6 u% C4 v8 g8 Y& zUSES_CONVERSION; 6 {6 \' d9 R% I4 C* u
CLSIDFromProgID( A2W(szProgID),&clsid); + G* C' U3 P3 q' T  o
将Unicode转换到ANSI
  K  J/ }$ E$ Q9 x% @4 D: l: L(1)使用WideCharToMultiByte,例如:
8 E9 I8 m* _% r  I// 假设已经有了一个Unicode 串 wszSomeString...
4 _; Y' P" V" F+ l0 e4 ^char szANSIString [MAX_PATH]; ( Q5 q* h  v4 v
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); % ]6 z$ \  R: {
(2)使用W2A宏来实现,例如:7 x! L( {4 S4 ^* f% |: J1 V4 c
USES_CONVERSION;
4 @& w) V' _2 u5 DpTemp=W2A(wszSomeString);
! x( K' R! R) E8 ~% Z$ P$ J8 f八、其它
& D( \& L$ T( v9 \9 v4 o
; N0 v* V% i/ c4 s; @& W对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
6 Y- H* D7 J: e$ h2 D, g! OLPARAM lParam;  |: k' C4 |0 B: J, m+ X
WORD loValue = LOWORD(lParam);///取低16位. h; p4 m% ^& ~, V% |5 o( e+ ]
WORD hiValue = HIWORD(lParam);///取高16位
( ]% C8 C, m: c: N. {) |/ V& J6 h8 l6 p1 K

3 y, g0 h9 O5 D; I9 w& _) Y对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
% Y3 Y/ U2 P& M6 tWORD wValue;- V# J9 H, N1 n5 u* Z5 O, H
BYTE loValue = LOBYTE(wValue);///取低8位! f0 I! X, i: B2 x8 E* E( L8 p
BYTE hiValue = HIBYTE(wValue);///取高8位0 c6 T9 U- {7 Q9 z1 A5 e- s7 i

1 a) _% X9 @* O+ L
' z1 r* o" E& O; ^# e$ U" `6 v两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
, N7 i. u0 l9 \% \LONG MAKELONG( WORD wLow, WORD wHigh );
- Z( Y. O9 ?' p) o+ f3 jWPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
7 ^* E; t% p! a/ HLPARAM MAKELPARAM( WORD wLow, WORD wHigh );' C8 k+ I. R* ?9 G: m, z
LRESULT MAKELRESULT( WORD wLow, WORD wHigh );
+ G3 `/ V! ]  u' }. j" |! z! T* R3 g4 i+ Z! T- H/ ?# ?. B$ W- h
9 N; {1 p$ r; f# ~  W
两个8位的数据(BYTE)合成16位的数据(WORD)
. Q5 ~, v2 p( c, x8 hWORD MAKEWORD( BYTE bLow, BYTE bHigh );
! K# ?! W6 V4 \1 A
" q# V; S0 G+ v& P
' z0 s2 H6 C0 }1 H6 C从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值: ~2 U9 _1 b; t% }  ?, B. U! r: q
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
# J, H( C' |0 A4 Z  \2 w例如COLORREF bkcolor = RGB(0x22,0x98,0x34);, {1 k3 ^' `& c4 N& @

& B+ p% b6 Q6 w: H# {* d; W/ z% M1 t, @/ d5 H4 ]0 N
从COLORREF类型的颜色值得到RGB三个颜色值9 G% g& ?6 H# y
BYTE Red = GetRValue(bkcolor); ///得到红颜色
2 p* N. S! i  j' {* s9 QBYTE Green = GetGValue(bkcolor); ///得到绿颜色% q, I$ k' o( |- \  t: A  b' y
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色1 p8 ~8 h, V9 h$ I& A; A2 w0 |

- h% J5 c# \3 `  q1 i& b9 E九、注意事项' M! K; t2 c+ G
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )
; R. B' }7 Z% X0 d3 i' _/ j; g8 j4 }& J& T
后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-10-2 00:29 , Processed in 0.034028 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表