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

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君: e# d! j4 d3 A/ `% _2 H. l
! p! I9 t. U" ^& {  S% l( }" @
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。  z) W3 B" a. s3 l4 ]$ M+ ?

5 q$ d9 v2 G8 v我们先定义一些常见类型变量借以说明5 x3 B, t& H* S. `+ G. P) o; R
' l* q: g8 T, o4 M9 z
int i = 100;
5 a# K8 [: @/ V+ t; ~long l = 2001;/ t7 c) r8 v8 Q9 k: c
float f=300.2;( a' N! ]% E  E2 J' \# ]2 M% [
double d=12345.119;! v1 u) y4 _- p5 e: y( Q" B
char username[]="程佩君";( T! ]! E  d  s& c) {
char temp[200];
5 n; N9 u5 Q0 M1 R! _) ^6 Pchar *buf;+ ^$ {' y6 ^! j
CString str;
- h9 j4 s2 R3 }$ j4 o3 ]6 s_variant_t v1;
. d( W' g6 J8 G1 y4 T_bstr_t v2;
. r* H; |! d4 A+ h. p9 a2 A/ {0 u$ `4 ]! a. Z: c
一、其它数据类型转换为字符串
6 X& S, Q  }2 ?+ `5 i: L6 R5 S
2 Y1 ^- T) `# T7 `" e& M. Q" |/ N9 ^8 Y+ p# k  c2 u
短整型(int)4 ]4 Y2 S9 @8 r
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制- c9 k4 W( h/ `
itoa(i,temp,2); ///按二进制方式转换 ; E7 L- [/ S4 D* U) m7 Q; Q% s
长整型(long)! l9 I) h  [$ Y3 s- c
ltoa(l,temp,10);
+ J/ b( }: K8 M9 B, t9 j3 _浮点数(float,double)# G& S1 `  k/ J; E, {
用fcvt可以完成转换,这是MSDN中的例子:- I/ L8 E/ l% Q2 w. g
int decimal, sign; ' _- [* ^. y  ?! N# v6 Y9 f6 r
char *buffer; 0 \  L2 U( Q9 U$ R/ l' J
double source = 3.1415926535;
5 c  \+ i( Z5 M$ ~$ S3 v' kbuffer = _fcvt( source, 7, &decimal, &sign ); 5 m9 I8 H6 R$ m+ \8 ^6 P4 a
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 06 H0 E$ b2 T. C1 }9 H& V
decimal表示小数点的位置,sign表示符号:0为正数,1为负数 0 h1 X& A' |; x, E# U$ {4 V
CString变量
4 C) F+ Y9 m7 J% u9 k5 P8 O* Jstr = "2008北京奥运";
: x* P0 R4 [. \5 h4 d1 K1 T2 y, ubuf = (LPSTR)(LPCTSTR)str;
- d9 ]' ^1 t2 {& W8 ]* SBSTR变量
4 M! [" m! z( U! T% s- xBSTR bstrValue = ::SysAllocString(L"程序员"); 7 P+ {" R0 C0 d5 x7 X
char * buf = _com_util::ConvertBSTRToString(bstrValue); $ w$ w7 w# S5 v* e; f
SysFreeString(bstrValue);
+ O5 q+ q8 Y8 V; jAfxMessageBox(buf);
8 t2 s1 i; V# a; ^delete(buf); / c' d" y2 @% D# V
CComBSTR变量' ]" z! `- a3 L# h1 q4 |
CComBSTR bstrVar("test"); 0 u8 X( ^. R" r4 E' X9 c
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
, O' z  ^) C6 o( G/ l1 r$ ~+ C' Q0 d# @AfxMessageBox(buf); ' I8 Z1 t* }3 h5 h& s1 n7 L
delete(buf);
! R; F2 }4 m* I' F2 k( h4 R& u4 L  J+ J; y6 T5 n
_bstr_t变量' Z5 G" R- M7 a' W8 Q6 b
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用: e/ @5 c$ a7 h0 ?" q' `- i
_bstr_t bstrVar("test"); & s; }, L/ r5 Q2 k" w
const char *buf = bstrVar;///不要修改buf中的内容
9 f/ q; Z3 {' r: Q; q% LAfxMessageBox(buf); , ]3 K2 K* Y3 d+ u' J7 p0 t

& D+ ?" Q0 ^+ m: r. b
% H* a$ J3 @% C通用方法(针对非COM数据类型)
9 k2 H6 f: I* N2 j& W用sprintf完成转换# O9 @- F2 h% F
char  buffer[200];, W8 R# k& Z/ Y% V; i# O
char  c = '1';
7 ~% m$ A8 K" D6 Jint   i = 35;
9 k7 M( b. W# rlong  j = 1000;6 ?* E/ r6 ^- ?& h  Z5 [8 o% g
float f = 1.7320534f;
( X# ^+ N+ w! R$ W' {8 |+ Asprintf( buffer, "%c",c);
9 O; S; K. t# k2 Wsprintf( buffer, "%d",i);
  v1 t0 n% K: y! U/ Hsprintf( buffer, "%d",j);$ y# L* C- f, w' d
sprintf( buffer, "%f",f);
8 g- {4 j( H7 ~4 \
" b: T/ O2 J) e2 M; e& N8 S3 \二、字符串转换为其它数据类型; {& B, l, \5 B0 {
strcpy(temp,"123");
0 M) w- Q8 T: e  g+ |# u1 K; D+ M" v* V/ [
短整型(int)( m! h% J! z0 \$ ], M9 V/ M! D) G
i = atoi(temp);
' c' k8 w5 y& O3 U4 T' [长整型(long)
5 K: @& z( D+ R7 i/ [: fl = atol(temp);
6 @, R! t/ R4 a/ d浮点(double)
. z- ]9 p# j9 ^0 F+ dd = atof(temp); . Y+ O2 V% @& z2 M! G# J) y
CString变量! V5 Z6 g! \3 a4 n
CString name = temp;
& ]! v7 i7 h4 U0 u, EBSTR变量
8 x. e, m  F# Q  F- a8 W- H4 \BSTR bstrValue = ::SysAllocString(L"程序员"); * X5 _" w: X% Z6 l5 F% v
...///完成对bstrValue的使用# q% N% a2 a0 U7 b2 g! e
SysFreeString(bstrValue);
0 |, O) L: q; D+ U. Z/ T8 f+ b# A
CComBSTR变量, l; W+ t6 z5 Z7 k/ m6 |# [/ e- u
CComBSTR类型变量可以直接赋值
9 k6 N" \7 ^/ i' M# H- s4 oCComBSTR bstrVar1("test");
( b0 q: I  c4 X" V% C4 L4 I1 F, TCComBSTR bstrVar2(temp);/ v7 t% [* F* a1 b' r. ?2 @
5 A) Z# H0 @. F
_bstr_t变量
* e  r4 u1 T+ q/ N" p5 I0 d( a_bstr_t类型的变量可以直接赋值$ x- |4 d, T( V+ Z
_bstr_t bstrVar1("test"); / S* e. h% I( U& R
_bstr_t bstrVar2(temp);
. y9 V# e+ R; v# |; q
( O7 i5 O0 a9 B" Q# o0 |2 r+ I
* D' D2 j% {2 v2 b0 X4 U三、其它数据类型转换到CString* |$ ?; {/ @. P) t
使用CString的成员函数Format来转换,例如:/ H3 t: h# s- p1 ^5 x
: p4 {) ]/ t& R
) G- |8 J' e& k" a6 @8 R
整数(int)
, B) \4 I1 U$ s3 G7 G; \, |4 Wstr.Format("%d",i);
5 M* `. {$ c( m浮点数(float)
- u4 r0 e3 C# |1 U% ?str.Format("%f",i); 1 {2 R2 ?7 c! _
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
+ {* n9 C- j- v! b& f1 S0 ystr = username; + j3 {  o$ n. w: I5 X$ R
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。7 I" I" r  ^* D9 l2 {7 a. O
" Z  N3 I& v, I8 v" s; G
四、BSTR、_bstr_t与CComBSTR
2 }( D- e$ g6 z% i0 k8 @& V, g& g& m, w  J, S( l

. I# g0 B: t, e# wCComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
0 w" q5 Y/ {9 C7 j$ ^+ P, tchar *转换到BSTR可以这样: 3 Y$ a: Z, Q( u9 q% @3 o: h7 f
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib* x( @# a; H6 k- _# K
SysFreeString(bstrValue);
% ]# F- D0 F0 _5 G+ n, C0 X" |% G反之可以使用
- ^' g/ @* H) Schar *p=_com_util::ConvertBSTRToString(b);# a, W* j2 j( ~0 `4 S* u
delete p;$ J" E0 X0 m/ R- q( S4 _
具体可以参考一,二段落里的具体说明。& G: n4 |. Y; B0 m9 L9 I
% N. `+ C$ j* i5 f
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
+ B  n8 s8 ]  v( w6 x) r5 E4 h7 k特别是_bstr_t,建议大家使用它。  p. |! Y2 A% E
( `$ J. g# l  g& L0 W" u8 X6 M' T

$ s' K$ V. f" O3 F! ?: k五、VARIANT 、_variant_t 与 COleVariant
2 r" k* ?9 [0 c* ?
/ h1 A% M2 I% A' Q2 |% w  R! E2 a9 X: @
) b$ K; V  l" lVARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
+ W  o% Q" R* e! d! z/ T* X对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
: v, O4 ]) N4 V0 @; T! JVARIANT va;5 [, T3 C3 K- w* e$ Y
int a=2001;
. H# [5 e) q) n1 y9 Z; Lva.vt=VT_I4;///指明整型数据
) E( j4 S1 S# g. S) s) }va.lVal=a; ///赋值0 `" D9 F" G# K5 C7 e7 C
7 N3 p% @3 ?1 F( D# ]& Y# V1 E
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:6 P8 q7 d# H7 f; o5 \- D

1 {  p2 j. c! G" j. uByte bVal;  // VT_UI1. $ f7 z# }! c* z# W" C" @) D
Short iVal;  // VT_I2.   }. p, T' R* E# q; b1 [/ i
long lVal;  // VT_I4.
5 F  S# N2 @' `, W% R2 _float fltVal;  // VT_R4.
1 F* V3 z/ }" c0 w6 ^3 s2 d: j+ mdouble dblVal;  // VT_R8. 4 u' L9 e) j8 E
VARIANT_BOOL boolVal;  // VT_BOOL. 5 Q: i7 I# Z+ k5 H  z
SCODE scode;  // VT_ERROR. % s+ H  M/ ~( ?  M
CY cyVal;  // VT_CY.
8 L: P; j9 e: {- |5 ~DATE date;  // VT_DATE.
$ I3 E- @- I7 g0 D+ c  ]BSTR bstrVal;  // VT_BSTR. & H( ]8 T( f$ g8 ?
DECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL.
; _. Y) I6 }6 f3 Z! FIUnknown FAR* punkVal;  // VT_UNKNOWN.
7 p2 H  {7 l0 i1 I$ U6 A5 wIDispatch FAR* pdispVal;  // VT_DISPATCH.
% t8 H1 t$ H, g( z% ASAFEARRAY FAR* parray;  // VT_ARRAY|*. 0 T. n( _+ j% N/ m9 C% d
Byte FAR* pbVal;  // VT_BYREF|VT_UI1.
, y( \9 [& Q1 u; T# Wshort FAR* piVal;  // VT_BYREF|VT_I2. 4 ^0 m7 r4 M1 p; ]+ \
long FAR* plVal;  // VT_BYREF|VT_I4.
+ h# ?7 u0 N" mfloat FAR* pfltVal;  // VT_BYREF|VT_R4. 7 A* G- |. L6 ]1 ~% j  }! \2 S: t
double FAR* pdblVal;  // VT_BYREF|VT_R8.
. u: X( x: K& PVARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL. 1 A+ s! u7 L" }% H0 N/ T7 p! X
SCODE FAR* pscode;  // VT_BYREF|VT_ERROR. 1 t8 K- {. }& `2 U+ |) c( u$ E. O1 t
CY FAR* pcyVal;  // VT_BYREF|VT_CY.
! ?5 V8 O2 @/ a7 [6 h" H4 cDATE FAR* pdate;  // VT_BYREF|VT_DATE. / k" M6 a9 D$ d$ {# N
BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR. ; M+ m0 J- T, f* |: M% k
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN. 5 q$ ?" r! m; n* z
IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
$ _! j, l; q% i7 c/ |. S! L. XSAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. 6 f0 m6 e% z1 A+ D
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT. - {/ E3 U: A6 K) d( t9 v
void FAR* byref;  // Generic ByRef. ' o  C; o: j- s) D1 h1 @
char cVal;  // VT_I1.
" g- L1 L2 b. u' X" \/ U2 @' y- gunsigned short uiVal;  // VT_UI2. " D; S5 T, H% m  S3 p' Y7 X
unsigned long ulVal;  // VT_UI4. 5 Y4 f! v% }' u# c7 d: ]/ x
int intVal;  // VT_INT.
  X2 f5 |" _- Munsigned int uintVal;  // VT_UINT. 4 |7 d" ]( Y+ D
char FAR * pcVal;  // VT_BYREF|VT_I1. 4 L8 V! W& P# z
unsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. 4 p6 B$ W- A2 ^8 A) n; I
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4. # T) [4 W/ P$ B- \  Y
int FAR * pintVal;  // VT_BYREF|VT_INT. 4 w4 C( b  ~# o& X4 H( Y
unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
4 b. _9 n7 Z/ x# m6 U* z+ {5 U# x3 X; I
$ z7 @" \3 s( a6 {0 B' K: I& i
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
: `  E9 N/ l  W使用时需加上#include <comdef.h>
" L1 |  I: i+ `/ @( [& j例如:3 R2 \( w/ p+ F+ M( _0 U0 P7 B
long l=222;
; w0 m9 D" W8 Q" e4 N( aing i=100;& M' O7 c8 |* |3 u) `
_variant_t lVal(l);
; j6 W! \4 c6 N" J8 ]* l" F  M. c5 S* XlVal = (long)i;
# R: V) h" ]+ B8 ]3 V7 L( \, q4 w( v

) ~0 g/ B0 w; X9 C. l5 A; E/ Q% TCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:9 ^8 N2 V5 B3 i8 @
COleVariant v3 = "字符串", v4 = (long)1999;
2 N/ C2 O4 d5 ]2 j3 C- c0 T& BCString str =(BSTR)v3.pbstrVal;8 S1 t/ D( r+ K- f
long i = v4.lVal;) U' F% M& t! G! u  ^1 y0 N' n. r% G
5 N5 r5 I3 \# ~- X5 o

. T5 V: X) O/ T$ ], o* a! n六、其它一些COM数据类型
$ z5 M% T  @8 E% `- w) v* S4 O, \3 O, m# r2 P
根据ProgID得到CLSID
9 f1 |/ u8 m5 S- PHRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
' M+ f! x/ g& F* L' ~5 a. Y/ VCLSID clsid;
. P* }3 [- Q5 SCLSIDFromProgID( L"MAPI.Folder",&clsid);) u0 n' ]+ ^) ^7 _

6 c$ [, H7 C' j+ e$ D3 w根据CLSID得到ProgID) S/ J. B5 I. A4 g9 [
WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
4 t) p5 t/ b1 j6 q+ p5 k例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
% Q( N! }& B/ [' n2 [6 NLPOLESTR pProgID = 0;
3 T/ r, O& X) ?ProgIDFromCLSID( CLSID_IApplication,&pProgID);- H( l. _% h" n9 g* \" D
...///可以使用pProgID
) Z# E6 r/ u9 rCoTaskMemFree(pProgID);//不要忘记释放
' a7 n- X% U; ^7 ]; T0 D# B
' q. R/ ?6 b- y$ E七、ANSI与Unicode
( B+ B9 j9 ~; G# P9 _% X0 [Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。( O) j: J) A! \) ~

1 l2 b& P- w2 ^2 L! s将ANSI转换到Unicode; I) P; W! M6 l& F' w) X
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);0 I7 N) |2 |3 d. p: t
(2)通过MultiByteToWideChar函数实现转换,例如:
, w; a' y4 o' ~char *szProgID = "MAPI.Folder";- H* @2 T1 D; |9 P" f
WCHAR szWideProgID[128];
/ f/ q8 S: }( g5 P, s& d, \5 C* hCLSID clsid;
! J1 h; X" m9 M! Rlong lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));* n1 x7 f6 `: H/ X, R" Y
szWideProgID[lLen] = '\0';
0 g; T- i  s1 {(3)通过A2W宏来实现,例如:
/ J7 Z# U. D2 Q1 Z% `, m, u7 t: SUSES_CONVERSION;
2 R' k  H1 a: L% G# u+ V1 kCLSIDFromProgID( A2W(szProgID),&clsid);
$ P3 J) p9 k( U/ v3 ^将Unicode转换到ANSI3 [( X7 i) p+ O- h8 \& V& s- _
(1)使用WideCharToMultiByte,例如:
. k9 s4 F5 r7 p; r// 假设已经有了一个Unicode 串 wszSomeString... 6 Q+ e' h4 H( F# d0 v' k
char szANSIString [MAX_PATH]; - ^% V8 D% v8 d6 |- \
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); 8 Z8 V! b. k' F8 C% R
(2)使用W2A宏来实现,例如:% h$ M) s6 J" F
USES_CONVERSION;
0 i/ B; V* k  `" c2 ^pTemp=W2A(wszSomeString); : }- A1 h( }4 \
八、其它- j" d2 C1 K, m; F! `- b6 h! r$ Q4 F

# q, G" i$ J$ n对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
8 y6 Q7 s- C, P# N$ wLPARAM lParam;- o6 K& K8 W1 P7 ?& I. R: X
WORD loValue = LOWORD(lParam);///取低16位6 s- t  G8 D( x( i& s4 `
WORD hiValue = HIWORD(lParam);///取高16位
2 E9 D# p7 J2 X8 t6 Y+ o$ V$ A; r6 l* H1 s* x9 J1 i

! E8 l: P6 E* _5 v' G7 o$ P对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:8 E% o1 X3 I0 e- ^$ P. k% f
WORD wValue;  V4 j1 q* O/ ~% U0 T* _
BYTE loValue = LOBYTE(wValue);///取低8位
0 o) [* a( P2 I+ J  ^. qBYTE hiValue = HIBYTE(wValue);///取高8位
# k7 w0 H$ j) {& F
: a; B: ]6 i7 a+ h) g- C; U1 Q5 M$ ^
两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)* r7 X* q& ~0 X" x4 N* B
LONG MAKELONG( WORD wLow, WORD wHigh );
  L1 V( s8 B, _; V9 N* ?# M. ]WPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); / ]4 z5 b" n  v0 R# K
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
, e3 O+ z) E  G7 CLRESULT MAKELRESULT( WORD wLow, WORD wHigh ); 0 s3 J2 m2 T  F
* z# f. F- G+ s' ]$ D$ J/ C1 P

* M# b+ P$ c4 M4 W& k9 x0 U8 |! l' z两个8位的数据(BYTE)合成16位的数据(WORD)
+ U: L) A+ `% ]4 \2 G% V( PWORD MAKEWORD( BYTE bLow, BYTE bHigh );
! T. p  J' {# c0 r
1 `6 [( s' ?: T  g# h( }2 J, _( S" m; g5 Y& _) F
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
$ d& y$ r- a2 V5 t+ I2 ?0 b- cCOLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );+ W; b& Z) b% Y! h5 Z
例如COLORREF bkcolor = RGB(0x22,0x98,0x34);3 x6 u- N( v0 E+ D0 J; m9 ]# V

$ ?6 ]1 y2 [, Z8 w- K- J+ v) x6 ?
从COLORREF类型的颜色值得到RGB三个颜色值
" g# B& g5 q$ Y( G+ n5 A/ x) ^BYTE Red = GetRValue(bkcolor); ///得到红颜色9 K% K+ p" K1 M- b
BYTE Green = GetGValue(bkcolor); ///得到绿颜色- f$ b8 d- S$ ~5 }$ }
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色
8 k" ~# V/ V/ ]% q$ f. X- x
6 k1 ^# e, h3 c4 e- ?九、注意事项, R' L& F0 Y8 [. E. v
假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )
- b: z* B2 E6 B/ f
5 O4 k$ N% Z& b( B后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-2 02:37 , Processed in 0.017300 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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