找回密码
 注册
搜索
查看: 4701|回复: 0

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君; w; V$ s* p! a
0 T. W4 Z$ L4 J, B: @
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。
+ l: Y; e6 V2 o( f3 n4 x0 p* ^& w
我们先定义一些常见类型变量借以说明
+ o# ~1 k. h" A* W0 h
0 g% [; w+ n) z. Qint i = 100;) G. X4 G/ A" G8 h; N5 c, H2 h& N
long l = 2001;
7 t# i, i: K2 _( C8 y5 m- u" cfloat f=300.2;
! N* Q& Q$ p7 W, ]' q( D0 Ldouble d=12345.119;1 V+ S' t+ n# u( ^
char username[]="程佩君";
# _) D3 j& N" l' F3 qchar temp[200];5 K: M0 t+ T2 H4 `6 [
char *buf;( |/ u/ a6 T1 O: h9 W/ o$ p5 U
CString str;
- j; [0 S& p7 m! R- [) [_variant_t v1;( \' Y, K7 l. w3 r
_bstr_t v2;
2 o! Y% N4 z# J; D
) y- s" k; k$ b! j  G) P* W一、其它数据类型转换为字符串
+ y4 I; x  p9 K' r2 b4 E; L8 S% x4 Y+ Z8 E# h- m

+ r' P$ }5 b: L- B: [短整型(int)7 N& S% x: ^$ c
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制0 [7 Y( C& N! c/ j5 d. }
itoa(i,temp,2); ///按二进制方式转换
3 M+ Q! n/ v  F* ~; l" d长整型(long)2 g: l2 m' i% d6 r; X7 w4 B3 n
ltoa(l,temp,10); 7 F: |4 N4 f' X
浮点数(float,double)6 ^# i9 Q4 G9 Y. C8 ?3 K+ m# A
用fcvt可以完成转换,这是MSDN中的例子:( D% j! C3 n7 t6 W% Z
int decimal, sign; - R. D" C1 y  v3 P& Q8 l1 Y
char *buffer; 3 {% `2 T- T& ^. B5 ?" A' n$ _  O
double source = 3.1415926535;
; G- A* \4 ?. A, u; Z2 A* R" dbuffer = _fcvt( source, 7, &decimal, &sign );
2 b+ }) v# L6 H& q9 o: X( e运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
, c" \5 [' J) u1 D4 sdecimal表示小数点的位置,sign表示符号:0为正数,1为负数 # G$ w: Q, X  Y) p/ `
CString变量
6 r# R: J, `2 ^3 q: b7 estr = "2008北京奥运";
! H6 W: x- }  tbuf = (LPSTR)(LPCTSTR)str; ' J. y+ ]/ F2 J0 d/ [
BSTR变量9 P1 g( y! H& n" x7 Z# h
BSTR bstrValue = ::SysAllocString(L"程序员");
5 r3 }; ~" H& o* _' @char * buf = _com_util::ConvertBSTRToString(bstrValue); # l/ [0 ^! V6 W& v; e* v
SysFreeString(bstrValue);
! C& T- @: e4 a; @AfxMessageBox(buf); ; X0 F& I- k2 |2 V9 D
delete(buf); - K" V2 H- p3 j2 l2 B& }
CComBSTR变量- j' _/ R# V5 ?& ?
CComBSTR bstrVar("test"); + Q* z  y1 l5 q- ?- n% u; s
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
: ^$ ~! r8 y4 \2 u& [AfxMessageBox(buf);
9 B/ D! P# J$ ]& L, kdelete(buf); % q: [9 t2 ?, T5 A

6 x8 }* x) e, V9 A7 m_bstr_t变量
7 B/ k& x9 y$ S' G_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用; h* ~6 B- S' k' m2 P
_bstr_t bstrVar("test");
6 _: \# P/ I& e9 |( Xconst char *buf = bstrVar;///不要修改buf中的内容
5 t3 o8 W; P4 V/ @AfxMessageBox(buf); ) j. E8 `- n& f, ?: P

+ f3 g; U4 v% L2 ]1 k, b) M0 H
通用方法(针对非COM数据类型)% k$ P( F0 G5 j1 T) _
用sprintf完成转换
" P0 P9 x% r1 z3 Q. p7 I0 Y6 ]char  buffer[200];( B( s) E+ T0 q* v
char  c = '1';- C4 r& N: k; X3 @# q: t/ \! E
int   i = 35;
; I; w( u/ F; ~" u" {9 tlong  j = 1000;9 h  Q1 V$ h( h: ]/ m/ d
float f = 1.7320534f;# ^" a: G; I/ e! w7 z- `
sprintf( buffer, "%c",c);& `. I( o8 {' N& C1 u" g- W4 e: H
sprintf( buffer, "%d",i);. H: Y5 R: u! E0 p) q- q9 Q
sprintf( buffer, "%d",j);
) f- M" K& d- f! \, I/ f& h2 tsprintf( buffer, "%f",f);
  I6 V9 {$ h# G# X( o/ j: F, Y/ Q/ ]$ j2 I
二、字符串转换为其它数据类型2 T: L( ]/ [8 k% T' Z! _+ K7 F
strcpy(temp,"123"); . u) o/ u' E  L2 Y/ `7 v1 [
! M2 _7 b3 ^+ g, t2 c3 i
短整型(int)/ Y, N# U5 @; W/ H8 N
i = atoi(temp); , ^/ p, T. h0 L
长整型(long)6 J+ p+ a8 U3 c4 p
l = atol(temp);
$ _2 @1 O: m3 ]  C/ E8 F7 C$ J8 e9 }浮点(double)2 _9 ]  a6 e. Z% R: S
d = atof(temp);
* \/ H. }4 o4 h/ }0 Z7 xCString变量' k: ^0 e) L6 h* L  L7 z: w
CString name = temp; / y; d6 `5 t/ J+ o
BSTR变量 ; W& R4 G" J, d' h, s3 x7 O# c
BSTR bstrValue = ::SysAllocString(L"程序员"); : v. o$ K& A) d; }* u4 a+ z, E
...///完成对bstrValue的使用0 _( z; }7 f2 z7 w7 I; ^2 R! S1 I, {
SysFreeString(bstrValue); ; }, R8 b( J8 m$ c* ?) b
. Q% ~+ h) {- Y8 M% ^
CComBSTR变量7 X! Q8 T" h8 d. I0 Z" J
CComBSTR类型变量可以直接赋值
/ A* M4 S3 T0 u3 ?# K7 |CComBSTR bstrVar1("test");4 ?; m1 T% u9 c; v
CComBSTR bstrVar2(temp);6 o) \0 o/ B7 o' Y' d8 ^
% V) R2 v# z, `, ~# r
_bstr_t变量- t9 r+ r$ Z, m2 L# h) p8 @
_bstr_t类型的变量可以直接赋值! P2 [0 B  a) {% M2 x- H4 D
_bstr_t bstrVar1("test"); + Z6 ?7 S7 I1 h" |7 T
_bstr_t bstrVar2(temp); $ @9 e& A' j) g( o

# Y# w& f2 C  {2 i. I7 Q6 N) Q$ Z7 D& d4 j/ E9 i( d
三、其它数据类型转换到CString- |; W0 B; {7 ^- `9 O/ W8 J
使用CString的成员函数Format来转换,例如:
- z7 ~8 c. s* I9 b1 O6 q& M8 c9 C* M& W
5 }: H; _, D4 Q5 b9 O3 h7 C
整数(int)
- `0 K: m2 G. istr.Format("%d",i); $ t4 M& I( n$ B: g, }
浮点数(float)
2 v+ O8 f1 s& K# vstr.Format("%f",i);
' N0 A: }- k' F字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
9 d' h3 C* X3 Zstr = username;
7 }$ E. b% v; s0 o; L! L对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
% A0 {; P* D# n' X9 Z% k/ a+ y# L! p" K  B2 }; M" G# U
四、BSTR、_bstr_t与CComBSTR
. e+ h! s$ P& Y( F3 ]! z- ~' f2 E0 i( y9 x% g  O  @
3 l1 \2 a' `/ k- p. n9 P
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
0 f# s: t; l/ r! L! @: m6 Rchar *转换到BSTR可以这样: 9 }9 I8 D8 ]; ]6 i. y, }
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib; p' @0 n6 p" B1 F3 D' v7 O
SysFreeString(bstrValue);   V$ E, `" m1 m
反之可以使用5 T' u* _% x" y" U1 t+ ]
char *p=_com_util::ConvertBSTRToString(b);
6 y) w& i  f/ H, Sdelete p;
$ m' [4 Y1 O3 n( n) F; O- P8 f, C/ t具体可以参考一,二段落里的具体说明。& s. B6 ]5 G! r
- M( N+ o( ]+ I% w
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。; k/ c2 @9 k$ y5 O5 y
特别是_bstr_t,建议大家使用它。) v: \& l$ e- K2 V- D
# |$ F8 |+ B; [- M3 W  V  q
( {1 r% j7 F& @1 O  k
五、VARIANT 、_variant_t 与 COleVariant
( ?  M& Q1 @1 C* \$ L( H  d7 B' t
  y' D- J  w3 J2 a8 w; U+ p! g2 E8 d1 M. x: W7 y
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
3 W1 a9 H: Y4 B# G对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:. e& T% F4 u. r% j
VARIANT va;  E4 E; A( o5 i. F1 P! S. E+ S
int a=2001;
' `3 i8 p3 H/ S( o5 u6 t. eva.vt=VT_I4;///指明整型数据
8 p* N# I4 r/ C! W. Sva.lVal=a; ///赋值
6 v3 s& T4 x8 C  q( ^
; v: f9 x2 ^! Z+ u( ^对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:
* E9 G( I  g( K' \* j
# x! \& N/ z* n4 G) C( v; i% {Byte bVal;  // VT_UI1.
& s3 z+ G3 q2 uShort iVal;  // VT_I2.
7 h1 r1 _; D7 V: U4 U! i, ylong lVal;  // VT_I4.
" Z& t" @4 `7 H+ o5 Bfloat fltVal;  // VT_R4. ; x) R6 ]* P% a  C- q3 X
double dblVal;  // VT_R8.
8 Y: O7 Z8 P4 S) P8 Z& s: ~  p/ C% EVARIANT_BOOL boolVal;  // VT_BOOL.
, U6 e3 T+ z3 y; |: rSCODE scode;  // VT_ERROR. 8 g: X2 \3 N" l5 K
CY cyVal;  // VT_CY. ) C. j' R# v# d5 ^+ X% @
DATE date;  // VT_DATE.   a  ?$ j: m& @! C( o, w
BSTR bstrVal;  // VT_BSTR.   a" L3 \* p% J" e6 _  m
DECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. ; O0 c# m* V/ {; D2 _3 {, D
IUnknown FAR* punkVal;  // VT_UNKNOWN.
1 }" A  ]; a5 N5 y% ?- E  iIDispatch FAR* pdispVal;  // VT_DISPATCH. ' I0 C6 z* Z( L0 f
SAFEARRAY FAR* parray;  // VT_ARRAY|*. - f- g" l: a( g
Byte FAR* pbVal;  // VT_BYREF|VT_UI1. ) j% H8 Z' S6 I! _) Q
short FAR* piVal;  // VT_BYREF|VT_I2. 4 T. W9 W' i2 ^0 f
long FAR* plVal;  // VT_BYREF|VT_I4.
2 D9 ^$ K$ s3 p9 G& ~: k6 U& e) b$ \float FAR* pfltVal;  // VT_BYREF|VT_R4.
- h1 K) I/ j  z! R3 `! Hdouble FAR* pdblVal;  // VT_BYREF|VT_R8. . p9 h" ^3 K2 U2 [9 J7 l
VARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL. 6 r  t. i6 V0 U: l$ X# h+ _$ E
SCODE FAR* pscode;  // VT_BYREF|VT_ERROR. # Z, j& H1 t4 u) Q: w
CY FAR* pcyVal;  // VT_BYREF|VT_CY. / t3 w9 Y; t3 l, n6 {3 G
DATE FAR* pdate;  // VT_BYREF|VT_DATE.
0 P/ M6 }* a  L, t2 [BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR.
, \1 b) R) D+ GIUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
3 K: m! S8 O2 u' D. G. k9 @IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
' q) c( p8 E3 t' X% `0 i& z& gSAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*.
; ~+ O! T0 Z; `6 e, T! KVARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT.
+ m  L, k5 |! e7 Rvoid FAR* byref;  // Generic ByRef. # `+ `; \" l4 q, `3 w' i
char cVal;  // VT_I1.
0 _& w+ G+ d- E% Gunsigned short uiVal;  // VT_UI2.
8 T4 t7 @+ ]' l! W. y8 @4 p9 Punsigned long ulVal;  // VT_UI4.
3 N: n, s% l$ Q) ?1 K  A4 Z3 x( Gint intVal;  // VT_INT.   S1 m+ ~6 i7 r+ P& L: C6 X+ S( e& W
unsigned int uintVal;  // VT_UINT.
1 n- S% k5 h' `char FAR * pcVal;  // VT_BYREF|VT_I1.
* M4 y7 x: B8 n+ ~+ P+ cunsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. 5 V" [0 T' @' j6 ^; Z
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4.
5 A0 I1 z. s2 ^int FAR * pintVal;  // VT_BYREF|VT_INT. ' }4 G( w1 v# Q$ W2 }
unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT. ) x; O+ R: K1 o1 K" S# C" f# w/ I6 R9 k! N
8 L5 x* H& x& L% w: d7 |

) Q6 f# j% a7 r$ z- e_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。& z" r; w$ c  O( x# n
使用时需加上#include <comdef.h>. `+ ^  y; f9 ^
例如:
5 L5 z8 o8 {: N% U) w$ B/ Rlong l=222;" Z7 @0 L1 A* g0 y
ing i=100;
1 Q) y! c7 K. q# i4 X$ e_variant_t lVal(l);0 }' m- }) g- S3 z- M% m$ t2 A5 W
lVal = (long)i;8 c! c& U- D6 r  h# F; y
, Z: y1 L1 o  b# e3 i

8 Z8 ^( v( ?1 ~3 ~+ `6 b: tCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
" @& x! M9 ^9 R" `; O* S' RCOleVariant v3 = "字符串", v4 = (long)1999;* I3 w/ T# m8 l, ]" ^5 S/ D+ o& z  L
CString str =(BSTR)v3.pbstrVal;5 o7 g" w6 s3 N, L
long i = v4.lVal;% u0 X7 E/ [. B3 h( \
( k* J6 v( x0 I  c( F
& t" b5 J( R6 g, b6 c( R
六、其它一些COM数据类型! i- f- i. x) N- b, p9 Q

2 {* I) A# c/ F& u根据ProgID得到CLSID% r9 w: U6 n! B2 G# a2 u
HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
& t5 k2 P" q( C7 gCLSID clsid;
( A$ s* M( b+ [8 U3 u: s% n2 QCLSIDFromProgID( L"MAPI.Folder",&clsid);
1 o' A$ E: M/ I% Y% a9 _3 o
" B/ G1 s2 v/ A根据CLSID得到ProgID# |' \+ H% ^7 Z! V# z6 u
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); 3 v: g% D8 r$ j# ?+ X. N5 F
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID% f0 D0 V+ E) [2 o3 g3 z9 H* P
LPOLESTR pProgID = 0;
0 \1 \0 i' a4 I' F# D3 gProgIDFromCLSID( CLSID_IApplication,&pProgID);3 E" A0 G( ]5 c% k
...///可以使用pProgID 4 `; V! V6 i3 Q$ H3 [
CoTaskMemFree(pProgID);//不要忘记释放 6 p0 Z7 r- ]3 _3 w8 H3 l

" ]9 j+ z! J! \七、ANSI与Unicode
- R- Z  L5 s' w9 D! O! `Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。
' t1 s/ N% B8 E/ t: \' D
7 u: t/ h% b5 T% t; O! W将ANSI转换到Unicode5 G( G1 a4 f2 B( c: b/ ?
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
+ j: t  j8 a# _  ^(2)通过MultiByteToWideChar函数实现转换,例如:
2 m% z  t8 e1 k; I; a" Schar *szProgID = "MAPI.Folder";" E( K/ x$ y3 v2 k2 X/ O) P$ v7 W
WCHAR szWideProgID[128];$ w0 m3 @7 f! T: C# j# d
CLSID clsid;) [- w/ a' S; q! W+ T1 ^& T
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));+ W. h' c% Y4 }
szWideProgID[lLen] = '\0'; & w1 x5 {+ o" G" z: Q
(3)通过A2W宏来实现,例如: ) G4 j8 c, }9 t8 w# A
USES_CONVERSION; * ~. F& z  U2 O; I" ]/ h
CLSIDFromProgID( A2W(szProgID),&clsid);
( w  ], I& V4 O将Unicode转换到ANSI
( Q. W) s- x% G& A7 @& O  q8 |(1)使用WideCharToMultiByte,例如:
% v' f4 e3 v& R  Q// 假设已经有了一个Unicode 串 wszSomeString...
- a8 e" |2 B. N& v9 Jchar szANSIString [MAX_PATH];
( _6 x; s  d( \6 u5 iWideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); ) m: Z" w- l8 `6 ]1 D" p) _
(2)使用W2A宏来实现,例如:
+ G& D1 h3 F' c) _3 KUSES_CONVERSION;+ O( K: D! J$ B$ Z& U
pTemp=W2A(wszSomeString); 2 ]$ z; O6 j& ]9 q
八、其它  I# B/ K5 t2 p1 Z9 F
2 M. W. j8 @' b9 Y
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
+ @% g6 C& R/ C( U4 m7 ZLPARAM lParam;: T/ o) Q6 s4 H- @1 G2 U6 d
WORD loValue = LOWORD(lParam);///取低16位
& V; G( l% ]9 {2 FWORD hiValue = HIWORD(lParam);///取高16位
% n/ l5 m4 c) F  s# Q- c$ q! }- ~9 t( d  j4 Y' r: ~
  ^% \- Q$ G5 D  F0 U1 L) O
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:. S9 G4 x  N% x& G# p/ I  {: d
WORD wValue;8 m! R5 M8 N# z' |6 y+ v% t. Z
BYTE loValue = LOBYTE(wValue);///取低8位
$ T2 d  c9 J' Q* z2 @BYTE hiValue = HIBYTE(wValue);///取高8位
( Q2 I; C1 G% H; r) N- ]" I! N& p% z6 }1 r/ s

  r1 s9 K7 {# V2 e两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)2 j5 a: w9 {1 I8 [3 l
LONG MAKELONG( WORD wLow, WORD wHigh );
# k" y1 u, P9 Z! ^% K3 [6 _WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
+ m5 {* V: _+ x. t+ u' ZLPARAM MAKELPARAM( WORD wLow, WORD wHigh );
' ]# n5 ?; C, q) `' ]1 ALRESULT MAKELRESULT( WORD wLow, WORD wHigh );
$ v; C* u8 ]- j, u* W
5 a  O4 R8 @2 h8 t- Q" i
. b* y3 Y0 U$ m" D8 c  x两个8位的数据(BYTE)合成16位的数据(WORD)
/ t& \9 k6 [% W" X' qWORD MAKEWORD( BYTE bLow, BYTE bHigh ); ; e; ?8 V7 u7 k  z: W
0 b5 }& I& ^9 B) o
! |/ t' r  q* j. c
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值+ {- b0 n8 P- a( m& t2 _1 v
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );) P6 Q) z5 N& @" f. y: |
例如COLORREF bkcolor = RGB(0x22,0x98,0x34);' @; v! z2 }) R8 T: [$ t" m' K9 H

1 ~% J. S4 J9 g4 [! m) f: Q8 D" }& J( K: I/ X
从COLORREF类型的颜色值得到RGB三个颜色值
2 z4 k8 |5 I* C4 K" @BYTE Red = GetRValue(bkcolor); ///得到红颜色
+ P( \1 j5 l8 x6 m! c+ j+ i& _BYTE Green = GetGValue(bkcolor); ///得到绿颜色
0 E! N0 W0 o( ^- b$ u0 KBYTE Blue = GetBValue(bkcolor); ///得到兰颜色
4 F& [- ^0 U) S0 k+ j' ^; u# w4 ?. m/ D' J0 h
九、注意事项
% @& O# i4 B8 b- R假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )
& S7 j4 }9 x1 z; {: W
- g: o. x. f4 S* K0 M后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 12:16 , Processed in 0.019592 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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