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

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君
6 j) j8 O0 C* I2 ]* c1 [1 ~9 y' P: f5 @/ }$ A
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。
& \5 Z% @4 [! k- P( ]9 W4 J' |/ Q9 j  i& b  _" S4 h/ g
我们先定义一些常见类型变量借以说明# s8 Q. G' U2 s7 C& @
7 x% J/ r. ?+ f. P# L1 {
int i = 100;
; Q' E% ]9 a$ Clong l = 2001;
5 |" E3 }; K* b; a4 v3 g2 pfloat f=300.2;+ x( V( m* s  F2 s1 u3 ~
double d=12345.119;
, k, a2 |3 d* h. Y/ u  A) Ochar username[]="程佩君";! s' d4 j6 T( F% r0 r2 b
char temp[200];
* J. k+ E& ]) L* E' n! rchar *buf;
* K; T  X% w3 ]6 s5 c! TCString str;% x3 s- [$ F( ]1 x& }+ R
_variant_t v1;1 m* e- d0 U+ `% }
_bstr_t v2;
0 @/ [* k' K& X. e' s3 U' z/ F; |, ^7 L# `
一、其它数据类型转换为字符串1 ^8 C2 e3 b9 O/ w+ `* ^/ d2 t0 u& p

; s9 L) l8 I; H  [4 }
. V3 F* [' E- s. {; p短整型(int)# i1 }* ^! o# V  `% g1 G
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制# T" D, B9 W2 d# G. O5 N# J% y; ]
itoa(i,temp,2); ///按二进制方式转换 : ?' v* Z/ Q9 r" m0 M: d1 K+ i
长整型(long)
) m$ {, O& c5 J( M5 W* jltoa(l,temp,10); 5 Q1 [" w1 u8 @) \( _
浮点数(float,double)/ Q. a' @2 I7 Z- a1 @0 O
用fcvt可以完成转换,这是MSDN中的例子:4 T) K! y1 ^% d" t7 T
int decimal, sign; 8 e) ^% b- ^6 d+ d
char *buffer;
7 T! b) \  W- w' Zdouble source = 3.1415926535; + }; ?; w& {/ g0 E( D
buffer = _fcvt( source, 7, &decimal, &sign ); 9 |3 @1 C; P( L0 [8 r
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 02 z8 ]6 W3 Y6 ?* S6 e* T
decimal表示小数点的位置,sign表示符号:0为正数,1为负数 ' Q  X2 g' ^& A/ c! R
CString变量
2 X) |) Z8 K' |! @" H& N! Dstr = "2008北京奥运";+ \+ J) n2 z+ W2 t* V4 \/ p
buf = (LPSTR)(LPCTSTR)str; 1 P& c# T% p' e6 @1 E
BSTR变量' w6 _+ u+ N3 N) T' M: M
BSTR bstrValue = ::SysAllocString(L"程序员");
) t. y' S, g. Hchar * buf = _com_util::ConvertBSTRToString(bstrValue);
# e+ }& F* A6 d/ E6 ySysFreeString(bstrValue);   A/ D/ ?, w8 ^  w& K
AfxMessageBox(buf); 1 Z6 H8 l  P% |) i
delete(buf); ; O- V) E, O/ T  R3 S7 e# D( p
CComBSTR变量# h7 N& C4 t3 b4 s
CComBSTR bstrVar("test"); ; @' n; @& h# m2 G) {: `2 x( u
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
, z+ J7 t1 Z# z: @) ]" F" HAfxMessageBox(buf); 1 m# |" y, J$ Q9 b& W8 ^" ~& Z
delete(buf);
) o  B- ]* j6 u& n, N
  g: n' O7 v5 e_bstr_t变量; y7 ^8 _% u3 r
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用9 s- [# G& l' j
_bstr_t bstrVar("test");
" e: \5 T. C. B1 Y1 v7 a4 ]const char *buf = bstrVar;///不要修改buf中的内容
3 X5 }0 X7 i9 h% S% [) }AfxMessageBox(buf);
0 p! ?' H7 z* d5 e# F) u  q( t+ T! C6 R7 C
, C% d1 U! s: ?6 B" i0 V* E
通用方法(针对非COM数据类型)) i2 G1 [4 f( c5 F; Z/ p1 _! S/ r
用sprintf完成转换
7 i9 N  {0 Z  s  Z7 H9 Mchar  buffer[200];* M$ Y+ G1 J  `. U8 R& r
char  c = '1';4 M, m8 D! G  u
int   i = 35;' n! P  T" S5 _" W4 T! e
long  j = 1000;' p$ d. k% l, ?4 O5 u
float f = 1.7320534f;
% X3 i6 J" e7 F* E/ k) a3 msprintf( buffer, "%c",c);2 r. o) y* n- d' w! c
sprintf( buffer, "%d",i);8 a1 a8 T1 a) f8 ^" p
sprintf( buffer, "%d",j);6 H9 R) e6 I: A
sprintf( buffer, "%f",f);9 O; Z/ z# S/ T# k

% ~8 c+ b/ u3 Q二、字符串转换为其它数据类型& B- H4 W' G7 X+ Q" {0 Z
strcpy(temp,"123");
: p3 K: f8 Y% E5 C2 ]6 X5 b4 X3 @. o
; C' d$ O! w% R: V短整型(int)
, s( W9 v- W, F2 y4 a' w9 z4 K$ Ii = atoi(temp); : l& g4 Q" H: x0 U
长整型(long)
* H  H/ K0 f. j, O' Hl = atol(temp);
/ D% ^4 c; w$ j# ^& q浮点(double)
& w' M. |) U( O. |8 id = atof(temp);
0 q+ [: D& M! G5 DCString变量; v* `% ~3 |) Q
CString name = temp;
! `1 S5 T' s0 c- L: lBSTR变量 . G0 e9 a( W; e2 T# P" b
BSTR bstrValue = ::SysAllocString(L"程序员"); : e# X9 e- x4 e7 H" J4 {
...///完成对bstrValue的使用. H6 Q+ C/ ]2 q# X0 ^% y
SysFreeString(bstrValue); ) B' i& n2 B1 B9 w! Z8 a
1 W3 T3 [5 g& a; B5 I
CComBSTR变量
" g& C4 F  e8 P  U$ sCComBSTR类型变量可以直接赋值/ _5 l8 I# u  i2 u
CComBSTR bstrVar1("test");
/ R4 F& e& k3 @7 u; |; CCComBSTR bstrVar2(temp);
- I5 j: V( ^( O% o" W: T6 O+ N
% u3 Q+ V1 p( r) H) v% I2 Q_bstr_t变量
. V! X+ @, s6 m0 e_bstr_t类型的变量可以直接赋值/ c/ U6 x+ U! X9 \
_bstr_t bstrVar1("test"); 1 x1 w! O/ l" d, q! s
_bstr_t bstrVar2(temp);
' ]% R1 M/ y1 t3 ^- P" K1 z4 {- R9 f4 J; P1 x

) T& `" Z& O$ P3 N9 B. k% c& n三、其它数据类型转换到CString
% \% ]+ r0 t* [' [& Q1 L( v$ C# w3 u使用CString的成员函数Format来转换,例如:
* K4 z% C1 o4 v& K- R- K8 ^( ?
9 P: r' t* y' L) |, O. [4 q
2 @1 U3 C: |3 f" e# v( `, `: x整数(int)9 U, W0 |" _, H
str.Format("%d",i); ) k3 e# f- Z' q9 H+ v
浮点数(float)/ p( l: A# [8 v  M4 G& r
str.Format("%f",i); 9 O! F( m1 U9 v5 Y" U
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值* W: t# G. o" S% O2 Z4 y! W
str = username;
7 U: f7 k8 h9 V9 w3 b对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。  {' Q/ }! Y% \  m( \( V, u

2 ]; ]/ A. m$ B1 l" Q四、BSTR、_bstr_t与CComBSTR" g) O5 w& d, \6 ]$ L+ q, _

0 e- F# X' I* B+ [* x7 J1 m0 z7 |. Q
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
: r  b0 {+ i' y" R% v0 `8 a4 c, mchar *转换到BSTR可以这样: & K" G6 j. k# p  g$ h4 M# V2 U6 j
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib5 u5 I6 L0 b! J$ f& \
SysFreeString(bstrValue);
' b. w! Q  m/ I; U+ M反之可以使用
" g9 n7 m/ o/ \' }0 j7 H& Schar *p=_com_util::ConvertBSTRToString(b);
: [' x- q, ^) e9 Q' P$ Tdelete p;" J. Y. l& [2 s- @0 o
具体可以参考一,二段落里的具体说明。! U0 L" Z, k; }: h

: C5 i" G4 ~& x& P0 QCComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
- c% _$ o# n2 Z4 ?8 o* x特别是_bstr_t,建议大家使用它。3 c. R1 ?9 ~' P! x: Q( Q) C

, |2 M% Y/ m9 h+ I  }2 ^3 b
1 U+ S# A. H9 D! ?7 k; G五、VARIANT 、_variant_t 与 COleVariant2 I" o. s" C: C3 W/ [: H

/ e8 N0 \! m9 D! I, C: P. R; j$ M4 m# t6 W9 t
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。( r2 Q$ C% v; }+ E) Q2 H$ B
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:$ t# f1 {/ ^2 z6 \
VARIANT va;" Y) Z. q3 _0 H6 D5 D$ h4 F* p
int a=2001;
' K( Z7 p  o: j* N0 Xva.vt=VT_I4;///指明整型数据+ i2 t9 [/ O) Q9 ?
va.lVal=a; ///赋值
% B& c6 T; _4 ^9 n* K* `( F$ L# D& K2 z
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:
+ y6 B4 I+ @7 _5 [3 C5 y: N4 B" t: f& Q+ z, K; o
Byte bVal;  // VT_UI1. * d: q% ^: S) M/ [0 I" o
Short iVal;  // VT_I2. ( @! C% r" Y2 x9 Z, W
long lVal;  // VT_I4. / {+ e' ~2 z/ O1 @# h
float fltVal;  // VT_R4. / z( Y" {9 I1 Y8 L) J
double dblVal;  // VT_R8.
7 z) ]# j; J! Z4 y% vVARIANT_BOOL boolVal;  // VT_BOOL.
7 n/ q$ r/ z" USCODE scode;  // VT_ERROR.
' ~/ S  U. \# U2 J& x, {9 XCY cyVal;  // VT_CY. ( P2 z0 o7 O. O- B
DATE date;  // VT_DATE.
2 P9 c* m) w7 ~7 FBSTR bstrVal;  // VT_BSTR.
. K# b) \% u7 Y$ E1 F9 y7 Z) I, zDECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. 4 {# X% \" G, F
IUnknown FAR* punkVal;  // VT_UNKNOWN.
( n/ w) |6 s! R% L$ ]. Y) @IDispatch FAR* pdispVal;  // VT_DISPATCH.   ?/ b# A* S4 S$ u8 E+ Y
SAFEARRAY FAR* parray;  // VT_ARRAY|*.
2 v9 d: G+ d6 _+ {9 rByte FAR* pbVal;  // VT_BYREF|VT_UI1. # [4 A& E4 v& ^8 O
short FAR* piVal;  // VT_BYREF|VT_I2.
0 w) S( Z% T' y2 x7 plong FAR* plVal;  // VT_BYREF|VT_I4.
5 S* T$ }4 N! c! Z! c5 s, sfloat FAR* pfltVal;  // VT_BYREF|VT_R4.
# }, d: K, \% a! ^; ^, z9 `0 t0 ndouble FAR* pdblVal;  // VT_BYREF|VT_R8. # G- s4 |7 W- C3 Z8 H& d
VARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL.
+ i$ i+ v! D# N6 S4 K2 O  Q) fSCODE FAR* pscode;  // VT_BYREF|VT_ERROR.
# I/ `8 K4 i4 B1 PCY FAR* pcyVal;  // VT_BYREF|VT_CY. & G. g: A1 H% I) E2 j6 l
DATE FAR* pdate;  // VT_BYREF|VT_DATE.
6 P4 h9 W5 k; B8 tBSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR. + o5 T+ ~% v$ Z# {" ^! t0 A
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN.
9 t) X. V' l0 D7 R, |IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
0 m$ r* r! D  v: h9 _SAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*.
. A" C' W+ t7 [. R1 N( a5 KVARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT. % t( o1 ^( r' |& p, S' N
void FAR* byref;  // Generic ByRef.
4 p) o7 }5 u. d$ rchar cVal;  // VT_I1. ) O: t/ i. J  z( q
unsigned short uiVal;  // VT_UI2. 8 {7 O8 T- U9 h
unsigned long ulVal;  // VT_UI4.
1 L1 i  o' f$ dint intVal;  // VT_INT.
8 E" x/ _* J1 X$ ]' wunsigned int uintVal;  // VT_UINT.
% H/ ~+ }# D/ f9 W9 L$ Wchar FAR * pcVal;  // VT_BYREF|VT_I1.
0 f/ k5 L' |- f' [; h. u8 `6 m/ T% Eunsigned short FAR * puiVal;  // VT_BYREF|VT_UI2.
) Y3 {" z6 k! T2 C9 Z- |, l; z6 cunsigned long FAR * pulVal;  // VT_BYREF|VT_UI4.
! v* T. a( D, ^" H! ~3 Eint FAR * pintVal;  // VT_BYREF|VT_INT.
/ X/ ~5 G" \1 U4 Q3 e3 ~unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
7 T) t* C! i4 B+ O: b4 k" B8 ]% G! G& K8 P( T

) C2 G" N, f  F_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。# P; R3 l* L1 c! p3 `7 e# [
使用时需加上#include <comdef.h>9 b) o6 B5 X9 w/ P/ Y
例如:# f$ }' B( w. Y; ?5 ]
long l=222;
3 U% r# g* u: q) Q8 `$ G1 cing i=100;8 u4 W: F% W4 n$ G
_variant_t lVal(l);* z% m% o, u7 E' r% ]
lVal = (long)i;
2 K: i- a/ \) _3 K0 x6 @7 J/ X0 T( V1 w+ j
2 P1 `; i9 u, V
COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:% f7 V7 c) @: [: e! C8 m
COleVariant v3 = "字符串", v4 = (long)1999;
. V  @" o, t+ P; ~7 @/ V9 j' jCString str =(BSTR)v3.pbstrVal;" ]" @/ E& ?. Y
long i = v4.lVal;8 f4 I% J3 T; I  Q
* p: }+ J1 h" Z

, S- U2 ?! y# ?5 c/ B六、其它一些COM数据类型
9 m' q# C. K& P7 K' u0 A. w$ f; _6 T3 v0 {0 a* i; v9 U& \3 }* \
根据ProgID得到CLSID, W) U4 N- X6 _% y
HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);) D5 i6 f" a8 ~, b
CLSID clsid;
4 Q9 h$ W3 t) i! ]CLSIDFromProgID( L"MAPI.Folder",&clsid);; E" b. n2 f+ [# t

, c0 `- |+ l5 ~. S9 N' h: `. ^2 t8 f根据CLSID得到ProgID# ]$ i; L! x- a# B
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); ! j8 X4 H$ b7 z: J
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
" ]1 z3 x% @. _' b9 h# _, x1 vLPOLESTR pProgID = 0;
; s1 Z) c9 x! _+ V! u3 tProgIDFromCLSID( CLSID_IApplication,&pProgID);
- B( Y; k3 [9 _; l% x$ C...///可以使用pProgID * |9 F7 _. ^0 a) j
CoTaskMemFree(pProgID);//不要忘记释放 & ^$ z6 C( `) V" ]- K
" q0 f# f  c7 ~$ t( C6 N# D) A( Q
七、ANSI与Unicode/ }, f6 E6 k% X1 }3 N1 L! ?) p
Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。
  J- c3 J  o* \$ P- s
/ A/ O  w8 n. Z1 P将ANSI转换到Unicode( j2 p! ~! _% e4 m6 b* @
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
9 N$ `8 f- q) u, ?' s/ Q( A. ?" J(2)通过MultiByteToWideChar函数实现转换,例如:1 l  b! @% v) e5 R" t1 }
char *szProgID = "MAPI.Folder";
) U1 K  O) [% H3 M: M2 \WCHAR szWideProgID[128];
4 P4 X: \6 ?3 B2 g% k* F% E% k" lCLSID clsid;8 s/ |; B! T7 C- B* l' P2 \5 G
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
7 J5 M5 n# `7 d, K6 o6 bszWideProgID[lLen] = '\0';
' B. o$ t/ X% X( ^# \" ](3)通过A2W宏来实现,例如: 4 k. C' U3 [" H7 U1 a) u/ _4 k
USES_CONVERSION; " r8 X# z3 X$ _2 A
CLSIDFromProgID( A2W(szProgID),&clsid);
/ d2 y/ o. p( a( g9 k% u8 a" K- f2 E将Unicode转换到ANSI
$ I" X4 _- s  o; ](1)使用WideCharToMultiByte,例如:
7 t4 n1 r. Q) e" U1 d+ \+ u// 假设已经有了一个Unicode 串 wszSomeString...
# z8 _4 e/ m, N; i, f9 L* _) h  j' lchar szANSIString [MAX_PATH]; 7 R6 ?# z1 o2 e. X  _. z5 m
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );   q8 E# i: A' S4 ?
(2)使用W2A宏来实现,例如:& K! @# \- O8 E# F
USES_CONVERSION;7 M1 O% V( @; Z2 z3 m8 h& t
pTemp=W2A(wszSomeString);
* ~" ~  p* K/ `' f6 g八、其它
4 ~- o& C9 S& U/ p
% _$ d6 H; ^! P9 O$ w对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
5 U' k; b7 m7 B" |/ |8 jLPARAM lParam;
8 g9 h. n4 r$ j9 \3 u* M  pWORD loValue = LOWORD(lParam);///取低16位; b: G2 R$ R8 E! v3 l% a, O) _7 a
WORD hiValue = HIWORD(lParam);///取高16位
. l5 m3 I! h- W% G& u6 f! Z3 k5 j0 V& L. ^  j1 D: w+ f# U: |1 L; f! o
$ ~: D" ~8 X- i: W' E8 ^* d1 b
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
+ `) }/ A! w0 Y( S# s" uWORD wValue;: G: H; {7 N4 k( X1 w4 F
BYTE loValue = LOBYTE(wValue);///取低8位
' y. {8 \5 g& Z1 `6 S& uBYTE hiValue = HIBYTE(wValue);///取高8位
9 g3 e( Q* z% H3 b# q* v" T
8 Y+ [( K9 w0 Z: r. ]
0 T! w% [6 T9 U" m两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)' |( e5 d8 w/ F& n
LONG MAKELONG( WORD wLow, WORD wHigh );
! b( l8 U' `4 z8 i8 M, n# A  oWPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
6 }1 W$ x& p" N$ X0 R2 B2 y) RLPARAM MAKELPARAM( WORD wLow, WORD wHigh );
8 `# ?7 h) H1 C# G1 CLRESULT MAKELRESULT( WORD wLow, WORD wHigh ); - Y9 F6 r: C) C

' K- _. d1 R& B
$ g" Y+ }) _5 O" q/ a+ {! e' R0 K2 Y两个8位的数据(BYTE)合成16位的数据(WORD)- f* Q2 M: X9 b4 a) e6 q& b9 P
WORD MAKEWORD( BYTE bLow, BYTE bHigh ); ' O% e+ A- A+ v0 {* b

# v- @* i$ K# }3 ]8 h9 x5 \& U0 k" P+ G
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值0 K3 n4 _; [: w
COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
6 |% R2 {- d6 b4 U& |2 t9 |8 e例如COLORREF bkcolor = RGB(0x22,0x98,0x34);
/ U6 K5 o0 Z- O& \# E& k- r1 {

2 p; e* c+ N; L从COLORREF类型的颜色值得到RGB三个颜色值
% Q; ~& G, F/ S4 qBYTE Red = GetRValue(bkcolor); ///得到红颜色
: h2 O2 a# O7 uBYTE Green = GetGValue(bkcolor); ///得到绿颜色$ g8 `+ p- @1 a2 j. v3 D
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色
: n) {; n# V) ^; V% ?7 N, F, L7 F  z4 j* O8 F" \8 b
九、注意事项% \) C1 D0 P! t! S
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )) g" L7 _0 ]6 C7 Q; ^
9 e+ @& e% R% k# r: `) B; U" D
后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:35 , Processed in 0.019014 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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