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

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君$ W6 N% K  ~& M$ L* w5 O
7 e3 L1 F8 ~$ ~
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。3 r) e7 y3 o8 J& F$ K% G
0 M5 Z, S$ z* X5 _0 F; D
我们先定义一些常见类型变量借以说明" I. _# f1 x. W

$ ?9 h3 Y& I0 ^3 H+ ~. {3 i/ i' `int i = 100;
3 f, J' i4 K2 glong l = 2001;( d0 z- |. K6 q: i* t! o
float f=300.2;6 j9 e( ^& C$ H) |$ m1 D% u
double d=12345.119;
* y) W/ n! r+ X" q, C; Wchar username[]="程佩君";
" @5 l; g( u9 A& b) ^# b! V# Uchar temp[200];
4 X: j* N3 m& x5 s. ~/ {% ^char *buf;. P9 M6 l% g. a5 {5 d3 G; ~! s
CString str;$ G# I8 n* u) E3 O8 H
_variant_t v1;
$ X- Z, Z+ u: i7 m. g, c_bstr_t v2;1 f  x! A' H1 w3 f
4 U2 Q% n9 H: J) J0 o
一、其它数据类型转换为字符串' W/ j. U# p/ S! C9 I
. k. A* V" O4 f' q4 N
. R* E( B- m  y; f6 n7 X* p
短整型(int)5 s9 ]! C; a6 ?& _4 t5 A
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制2 m% _5 m& M1 M
itoa(i,temp,2); ///按二进制方式转换
2 O$ G- e3 |  j: C7 ^* h' e长整型(long)
3 J2 ?/ N3 Y. Z# Zltoa(l,temp,10);
) N3 d9 x+ v. m! m浮点数(float,double)
$ O1 H3 W8 S0 k用fcvt可以完成转换,这是MSDN中的例子:' _+ ]7 v! I( K9 N
int decimal, sign; 3 I; ]9 |9 K; O
char *buffer; 7 R/ c8 d9 `# ~) ^6 N
double source = 3.1415926535;
+ g" Q: n) @5 {2 f; Z1 Dbuffer = _fcvt( source, 7, &decimal, &sign ); : G6 d; Y+ A# i) e5 F6 t+ d2 N/ _
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
4 ~, M! G' X$ |/ e6 hdecimal表示小数点的位置,sign表示符号:0为正数,1为负数 8 E. T; ?! [) M" m
CString变量
8 o* J, i2 ]! |# o8 ~7 v2 ~str = "2008北京奥运";
/ @$ \/ Q: R0 ?$ Gbuf = (LPSTR)(LPCTSTR)str; ; E9 k& H; p& |! k6 D
BSTR变量* n! h$ C* N+ _
BSTR bstrValue = ::SysAllocString(L"程序员"); ( v' g% [6 X2 ~( H/ }
char * buf = _com_util::ConvertBSTRToString(bstrValue);
8 t1 v6 A3 |# a2 WSysFreeString(bstrValue); ! y# w2 M, C3 ]- R+ O
AfxMessageBox(buf);
, ~8 x" H2 E. g6 wdelete(buf);
6 i4 n! y. g) T0 ^1 i2 O* [( p3 ]CComBSTR变量
7 x" |7 S; a9 t' m" K: sCComBSTR bstrVar("test"); ; x3 z/ Y) }" u; Q- g3 m9 ^
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
: C" x1 j: u# I6 |" B" Y4 @AfxMessageBox(buf); % e. ~+ k# g6 b9 c% m& _8 r
delete(buf);
" ~, V; c- J" z/ n& E: m6 J
( I7 Z8 a0 Q* i: A) B( O7 P, g_bstr_t变量
5 r8 D: C4 c* f$ M5 M8 x_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
3 ]5 i% J+ t5 h% H% K0 I) d& G_bstr_t bstrVar("test"); 0 G- e- Z( H5 b, ]7 ?! R$ Z
const char *buf = bstrVar;///不要修改buf中的内容
9 `* T4 k- u* G; T" K/ W4 |AfxMessageBox(buf); $ x! ]$ V0 L) s5 M
8 O& r7 C7 T* }( E( R: M! N' K

6 Q9 o! L2 B5 q2 Q0 `通用方法(针对非COM数据类型)3 P' W, K* P7 Y/ v" l: a
用sprintf完成转换
, P" ~* v2 F4 P8 l  @. F& C6 Cchar  buffer[200];
6 N' v& l6 R( c0 W! I, q$ Ichar  c = '1';
& ]% U1 f! ^! [# s( R' z! y1 y+ Cint   i = 35;
" c, N5 U1 {  Q7 elong  j = 1000;
  h0 y3 [+ j/ U" v% Gfloat f = 1.7320534f;
7 ]$ U0 }8 ?/ N. M3 K  S+ }sprintf( buffer, "%c",c);8 p) \8 g- s: Z- j3 |
sprintf( buffer, "%d",i);
) Q1 b# h7 l6 i3 P1 bsprintf( buffer, "%d",j);0 ^# v: W5 A  m2 R+ v  e3 t
sprintf( buffer, "%f",f);( l9 w& Q1 L: C" Q

: t, s7 r# J/ e) C二、字符串转换为其它数据类型
6 g* _! F; n0 y( F: D* tstrcpy(temp,"123"); " W, m( r0 f4 z4 ^2 Z' E

" n6 F, Z6 H$ ~% X短整型(int)7 U/ [  R) z" {1 O: k
i = atoi(temp);
) @8 w  |4 |" H, i3 a长整型(long)5 O, G6 b% @$ r( J& E- `
l = atol(temp);
' D* U; W- V6 H9 T浮点(double)8 \$ Z7 C/ e. ]+ t
d = atof(temp);
" j4 G" H) O2 j, h' D0 pCString变量/ V! x' A4 c" }& S  }
CString name = temp; $ k. _) v/ F3 J3 |3 Y/ S
BSTR变量
! Y: L' m9 m  @) x& D+ I" F" lBSTR bstrValue = ::SysAllocString(L"程序员"); 6 L! w$ d. q) ^- _& Z* \& G6 \
...///完成对bstrValue的使用# G; L; o9 P/ M
SysFreeString(bstrValue);
' U3 |+ U7 ?6 M
! K) q$ S! N0 |* {  _% b$ e0 o/ g6 lCComBSTR变量
8 F! _; A) t7 E9 F; ^CComBSTR类型变量可以直接赋值, e! l+ ]' k# m5 ?' r- T
CComBSTR bstrVar1("test");3 @8 E9 v+ D/ ~
CComBSTR bstrVar2(temp);$ J& v  s+ W& U/ p- Z

0 {7 r3 s4 T$ C! P_bstr_t变量
4 d% T; n7 g' x+ y( G4 I$ r_bstr_t类型的变量可以直接赋值. F5 q1 t+ s( n
_bstr_t bstrVar1("test"); % V; n" s1 Q# ~% e$ Z
_bstr_t bstrVar2(temp);
& g4 @* {- }4 h0 A4 G: m
+ c8 B, L( X7 C. e4 c: E+ y" \( g5 W' G: ?. J
三、其它数据类型转换到CString
0 y- @+ D: W. R3 |7 s使用CString的成员函数Format来转换,例如:
/ A9 v% @4 P6 l2 c" w
7 Y# K$ A5 J$ y& h/ }% l' Z) G3 h8 ]1 M2 R: j* Z
整数(int), ~3 A5 |$ e& ^$ h7 f& j4 ?
str.Format("%d",i);
  y# v6 O+ i1 j  v& z浮点数(float)
4 x1 k$ b8 U& \1 c8 e! @9 b: [str.Format("%f",i); 1 P" m: C) D$ Q0 h, z" o
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值4 v% a7 g8 e4 _+ N1 l
str = username;
3 {4 Z6 E. b! Q* k& `/ c$ H, ^- c对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。- L+ Y+ C7 C. ]% O. [) h$ A
4 y" Q  W* _* o8 c
四、BSTR、_bstr_t与CComBSTR8 S* J  x+ r1 L" N) O

$ F. Y3 [) t" [3 ^3 O
$ z4 r! C1 a1 JCComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。% A, }3 V8 D% L* C
char *转换到BSTR可以这样:
4 j+ W" w, l, Y9 BBSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
2 u) r- g7 }/ M) B" W6 N4 |* lSysFreeString(bstrValue);
' t! {, k- t4 P- p3 x* W反之可以使用' C4 `2 @/ e7 b' v
char *p=_com_util::ConvertBSTRToString(b);4 }4 m% f0 _& `
delete p;
$ u8 J7 d- [$ D具体可以参考一,二段落里的具体说明。4 A' M3 P: L8 o( X* E& q
5 K" \/ p+ Y* E7 t7 W) e
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
; W5 D1 x( N6 t6 {0 O- T特别是_bstr_t,建议大家使用它。4 g- E5 R0 U6 d4 l) b
, W' o; `& y/ Q: ~
) a& a3 G* e6 s
五、VARIANT 、_variant_t 与 COleVariant
' _1 i! `9 a7 f2 X0 J; f- |% G5 h5 L  }* j! d; q
8 g  C/ D9 a0 ^2 V
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。, m0 l  G) u" I6 [) f! J- U# V. u
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:1 c. F" ^& _% `: l
VARIANT va;
4 w2 Z" c* a5 Pint a=2001;1 Y7 F& X, P9 U1 C, I$ q6 C5 M
va.vt=VT_I4;///指明整型数据6 k2 V) [; c# v  ]
va.lVal=a; ///赋值- u& H" l5 i, s# W, x* B
0 e9 u: L" w. f6 i5 x) y) G
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:
% X" P& ~2 P2 f( d! n" e
% p* L' d6 Q& e' j# dByte bVal;  // VT_UI1. + u7 s. a& A* A
Short iVal;  // VT_I2. & N! P# [0 H8 o- K! x$ p' F/ M3 s
long lVal;  // VT_I4.
! m0 m/ {0 M/ _% Z$ W6 Vfloat fltVal;  // VT_R4.
& [4 K# ~7 L1 e4 M6 Bdouble dblVal;  // VT_R8. & v; r/ I" F6 Y0 o3 b+ o  E" m  H
VARIANT_BOOL boolVal;  // VT_BOOL. 7 U, K, k- h3 Z6 K# d. ?
SCODE scode;  // VT_ERROR.
) w, a' j  `2 [- W3 [CY cyVal;  // VT_CY.
' s; ?" ^# k  j( qDATE date;  // VT_DATE. : v% m& B- ^7 m
BSTR bstrVal;  // VT_BSTR.
+ _" N, m. v/ A7 sDECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL.
( o/ H) B- ~7 A: G- UIUnknown FAR* punkVal;  // VT_UNKNOWN. $ I9 ?: m$ }% F: }
IDispatch FAR* pdispVal;  // VT_DISPATCH. # j( {2 v; t9 P4 b
SAFEARRAY FAR* parray;  // VT_ARRAY|*. 9 V  z; ~: e4 ~* X  j& C( w8 n
Byte FAR* pbVal;  // VT_BYREF|VT_UI1.
9 n5 q! P6 a* j* Fshort FAR* piVal;  // VT_BYREF|VT_I2.
" r* R& p! {$ v% Mlong FAR* plVal;  // VT_BYREF|VT_I4. * k" V( u/ E) H: o. g+ d- i. D+ P5 h
float FAR* pfltVal;  // VT_BYREF|VT_R4.
0 E) ~5 E; v( q. S8 Ldouble FAR* pdblVal;  // VT_BYREF|VT_R8.
- P  E( G/ [$ q$ z& P! `2 ZVARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL.
+ X3 D2 e5 I7 L$ D! O3 hSCODE FAR* pscode;  // VT_BYREF|VT_ERROR. # g  Z1 W0 F$ y/ c* _' q
CY FAR* pcyVal;  // VT_BYREF|VT_CY.
% ?, ]) C' l! F$ u: N+ x0 FDATE FAR* pdate;  // VT_BYREF|VT_DATE.
  l5 W5 x2 _! \7 }1 I  X' K- DBSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR. $ [8 n: `1 j- ?) y2 \$ b% \& B
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN. ) Q7 X1 d! o" L- t
IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
: i: g0 _( J+ J& r( g: T: d$ sSAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. - `- u* e6 y" e0 t' Q
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT.
  x" g% z# K& l+ z! mvoid FAR* byref;  // Generic ByRef. 3 |) w, ?3 S, h
char cVal;  // VT_I1.   ?$ v5 E4 F2 K- n( O3 ~
unsigned short uiVal;  // VT_UI2. 7 c: m' U/ o- E/ j! {
unsigned long ulVal;  // VT_UI4. 6 S( b$ A4 `0 q/ G  a2 f2 |8 |
int intVal;  // VT_INT. & U" V& v7 p* q) m: K
unsigned int uintVal;  // VT_UINT.
5 w$ j5 O# o0 ]+ J) u" {! D  lchar FAR * pcVal;  // VT_BYREF|VT_I1.
8 r: o3 O# G! w  r, y0 e4 Yunsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. + q# L1 g, D; q! d4 ^
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4. , g  ^' \0 L2 ]1 w
int FAR * pintVal;  // VT_BYREF|VT_INT.
1 d5 C. t: U/ B0 funsigned int FAR * puintVal;  //VT_BYREF|VT_UINT. 7 C) i- ]5 ~7 A' a! N" R% j

5 C# n. C) O9 G7 P) m2 I7 ^9 W/ R* l3 v1 o
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。& O3 A9 M$ W! `' {8 `8 B( M. ~5 A7 \
使用时需加上#include <comdef.h>; N& G$ T+ S1 z5 N9 c# z' N- D$ I
例如:
( t/ R7 i! v% W7 r, Flong l=222;/ N: t& t; C$ c( x# R
ing i=100;
) Y( c: q/ B# Z- Q" k! O_variant_t lVal(l);' S7 e7 }+ ?9 D4 z* s/ J. s; e3 n. p
lVal = (long)i;9 ?9 Q* t* m1 c; D% V; w

$ p7 |- _2 D' |6 Y4 g
' M+ _! |& b8 }& l8 R# s2 eCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
$ v0 A# J- Z: T, n. x& H# PCOleVariant v3 = "字符串", v4 = (long)1999;
7 y3 A6 I" l6 [CString str =(BSTR)v3.pbstrVal;* B( O& q% A' X+ Q+ {& ^
long i = v4.lVal;
1 f8 C5 t& l8 y. s
7 I  u$ D, J: P3 d- V* q) P2 k, o* ]1 ~1 h$ T
六、其它一些COM数据类型  P9 @  W+ J" T3 B' H
# D- `# s% z' ]: j8 @* r
根据ProgID得到CLSID7 h& C$ G! p' t1 E
HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);& {0 c7 i' w& j$ K( B
CLSID clsid;2 F0 S( c9 L+ l9 f' c- B: J$ V* Y
CLSIDFromProgID( L"MAPI.Folder",&clsid);. H* z9 r( t! J+ d9 W! y  T
  ~7 B3 G+ I& _+ u) Z
根据CLSID得到ProgID( _% D! `& C3 T, h0 R( n( M" o9 k
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); * U: j/ U) S& I7 e# ~
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID, q4 n) ]5 H) J- W9 d7 C
LPOLESTR pProgID = 0;
- o7 a* @) I* D" [& o# zProgIDFromCLSID( CLSID_IApplication,&pProgID);! U2 U$ F( q: s: J- M4 G
...///可以使用pProgID
+ f' w: O- D. g/ ^- Y5 GCoTaskMemFree(pProgID);//不要忘记释放
% _8 u& ?1 w8 A; i; t2 T# N& t% T9 ]
七、ANSI与Unicode
+ t1 X* [' N0 A$ ^0 C+ y2 iUnicode称为宽字符型字串,COM里使用的都是Unicode字符串。
  ~- D4 \( v' F7 w0 }4 u$ I* f+ L$ f) Q0 i% }8 Q6 Z
将ANSI转换到Unicode
, _# O: f1 t" y7 q( z( R(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
, o" z+ D( y1 I- y" m(2)通过MultiByteToWideChar函数实现转换,例如:* C. ?/ i% ^* p' M* C. |9 l, L
char *szProgID = "MAPI.Folder";
8 N/ Y+ _: b3 c0 K4 @WCHAR szWideProgID[128];4 C6 m# a0 S# e6 T
CLSID clsid;
7 i/ }- N8 g: q$ d4 t  Y5 ]long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));7 ~( k" {. Y4 ~
szWideProgID[lLen] = '\0'; % Y* V% w5 P, u. Z" c
(3)通过A2W宏来实现,例如: 8 n3 N; N4 J9 @0 Q
USES_CONVERSION; 0 Z0 ^9 p$ W+ v
CLSIDFromProgID( A2W(szProgID),&clsid);
+ X( L" `3 V; D2 B5 D将Unicode转换到ANSI
/ x; C: b, Q& R! t(1)使用WideCharToMultiByte,例如:
! v) y- a- m! F// 假设已经有了一个Unicode 串 wszSomeString...
& T! h8 m- U! L+ d- `8 j8 Fchar szANSIString [MAX_PATH];
8 m" t4 ~4 z! [7 N7 h1 u, XWideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); & `! h3 {" }: `4 w$ y
(2)使用W2A宏来实现,例如:1 L& Q2 j) Z' o  z* x' i8 g
USES_CONVERSION;
, ?  t! s; m9 u# cpTemp=W2A(wszSomeString);
; D, k+ s3 Y' I: W八、其它
9 A& u3 t* v% n8 m# h1 q. E1 @. j) l1 [/ @
对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
2 N  @1 |) Z. N7 [. f" S# G4 d& ]4 PLPARAM lParam;5 S/ {3 Y" m% l+ f1 F8 f/ I/ o
WORD loValue = LOWORD(lParam);///取低16位0 [- S  s8 V7 I
WORD hiValue = HIWORD(lParam);///取高16位5 f; z* ^) w0 a8 D. _

  L6 C0 B* n5 {8 h% M$ J7 G+ t* W0 ~1 K( `) p$ u; Z$ ~
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:- {+ N5 P2 C9 s$ e' u) @
WORD wValue;
' c( D  O9 w& {5 q; v* I! HBYTE loValue = LOBYTE(wValue);///取低8位
8 }& Y1 s3 M! k3 @; I! GBYTE hiValue = HIBYTE(wValue);///取高8位" x( ?/ C, v6 n4 X2 V- Q" @) N4 j

, i: F/ Q. k0 Z3 a' i2 |# H1 F4 m% I2 W3 k8 \
两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
% H' V, g6 h! l# u9 ], hLONG MAKELONG( WORD wLow, WORD wHigh );
* \' S, i$ p& j! @WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
% N' y6 T* G3 s7 M7 V9 B% D7 DLPARAM MAKELPARAM( WORD wLow, WORD wHigh );
# n3 s5 D& e3 O8 fLRESULT MAKELRESULT( WORD wLow, WORD wHigh ); 0 E/ n4 ^9 Q1 t2 t
5 d0 @3 O: m! h) S6 t& y  T
( B( ?9 F1 |8 y% E- V$ k
两个8位的数据(BYTE)合成16位的数据(WORD)
/ b5 l" S/ k( G& X% ~! F4 {WORD MAKEWORD( BYTE bLow, BYTE bHigh ); : ]  i2 m. f7 {/ W! v. N

0 `) Y6 q/ a) @# `# Z" I6 y+ v! ?* B  V8 u7 p
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
/ n/ {( N" X* `- {* e" ?  v  fCOLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
; p" N9 q, f. p# K7 }/ q例如COLORREF bkcolor = RGB(0x22,0x98,0x34);4 Q5 |, L, h# c. ]: K
2 R  D+ Z# Q5 C* K, J) C; Y

7 L5 ^* ?- ^2 W% n# z3 Q$ n从COLORREF类型的颜色值得到RGB三个颜色值
* f- D; E/ k  {3 z1 h0 z4 e  QBYTE Red = GetRValue(bkcolor); ///得到红颜色' w) B% c  b9 L4 S) m2 A
BYTE Green = GetGValue(bkcolor); ///得到绿颜色
1 U& o& _0 f5 q/ i$ SBYTE Blue = GetBValue(bkcolor); ///得到兰颜色  U! B  O3 m0 Z* s8 {9 E, j9 v
8 ~7 w* `9 G' Q1 l
九、注意事项7 {0 w3 b6 a9 U6 r
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )6 T# [% c7 }6 T
2 F! d, P3 c1 n$ S* y
后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 21:47 , Processed in 0.018547 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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