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

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

[复制链接]
发表于 2003-10-19 13:17:07 | 显示全部楼层 |阅读模式
作者:程佩君& X* q, z$ K4 Q2 O! S+ }$ @
0 n1 Q, D' n' [
刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解,本文将介绍一些常用数据类型的使用。! G0 M# K/ |- ^( N$ t2 I8 v

$ ^' \& z7 U3 \4 V我们先定义一些常见类型变量借以说明
+ s8 ~+ C0 Z8 x6 \% c9 m, g+ j0 V" Y
* g1 ~1 g3 z  j/ m7 @3 K$ lint i = 100;; f  U. B; q+ S. @6 m% ~+ L
long l = 2001;. Y+ _3 e6 `4 ]  S
float f=300.2;4 u& A' f! X% B! V5 v' C- X
double d=12345.119;
3 m6 c8 ^  `- ~' F* B  A0 nchar username[]="程佩君";
2 u4 G& V2 f, lchar temp[200];4 s4 i" W$ {1 c" A8 y1 f7 w$ B
char *buf;+ [0 d% r  |# s8 c9 Y% Y
CString str;
- @. ~% J( A% ~- A$ t: W% Y: ?_variant_t v1;
7 J! L& B4 s: r2 J. k7 W9 V' F_bstr_t v2;2 A1 U) Y3 D0 d- P' I
" F7 e( o/ u2 H
一、其它数据类型转换为字符串1 F8 C8 ^! f) o

& |5 q* N5 X9 ~2 D5 l7 X( }: M
9 x* M7 ?$ S9 I  I7 S: M4 ^6 C( ]短整型(int)' `& S1 F8 g: E3 c# h! Z
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
/ R" L) E! R# G  ~* \itoa(i,temp,2); ///按二进制方式转换
; L2 S/ x: z) ^- t长整型(long)3 B, ]6 \4 H$ N) p% u) G* H
ltoa(l,temp,10); ; b, v1 v( {5 L) ?* r; c
浮点数(float,double)3 b) \" _+ y6 m; P0 g' q0 w
用fcvt可以完成转换,这是MSDN中的例子:. K; R$ g+ j4 {* k: E: z) i) M
int decimal, sign; , [* e% m& q  m# c; c1 s
char *buffer;
& `5 d7 T1 y7 |6 k6 _double source = 3.1415926535;
$ q, K6 C4 B# o  F( ^' w1 Q, K- ^buffer = _fcvt( source, 7, &decimal, &sign ); 7 d# E# T. ]7 {% b
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 03 b$ E. ?& N' @  }+ F
decimal表示小数点的位置,sign表示符号:0为正数,1为负数
* [) v; F/ b$ C2 {CString变量
# R% Y/ P6 d9 e! m% Ystr = "2008北京奥运";' z8 F& H, L9 x( G4 N
buf = (LPSTR)(LPCTSTR)str; - b, g, o$ u. W+ c2 q) ~7 A. M
BSTR变量
) V$ _- ~( Z" h/ t" }9 UBSTR bstrValue = ::SysAllocString(L"程序员");
1 _, q9 O* `/ H" Mchar * buf = _com_util::ConvertBSTRToString(bstrValue);
' W! Y$ q4 H; n9 L  {0 e% |7 xSysFreeString(bstrValue); ; L, ^. A/ [- e3 A/ v4 q( J
AfxMessageBox(buf); , ^  k$ |4 _3 Y7 @0 {
delete(buf);
' y1 ~9 y: w/ I5 J( e* q2 MCComBSTR变量
5 a& H# H( N' K6 }  G1 WCComBSTR bstrVar("test");
8 K% w1 P. D! C* }3 t9 nchar *buf = _com_util::ConvertBSTRToString(bstrVar.m_str); 8 {8 ?  ]+ X5 w8 S$ K  x
AfxMessageBox(buf);
% Y5 s: d  v5 Pdelete(buf); : l- ^5 G/ _2 m( {
) g/ q3 y% L) L2 Z
_bstr_t变量
* s9 p5 o9 `, ?! f  C' H4 B_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用* R! l% l0 w9 }: m1 ]
_bstr_t bstrVar("test"); ) f$ g. }1 a% s" S
const char *buf = bstrVar;///不要修改buf中的内容
8 h) s8 v9 U0 q# I- F" bAfxMessageBox(buf);
+ l$ q, Y5 T: d$ A& @4 H# T0 Z( n$ f4 ~9 Z
9 m9 c5 b) `8 P) }9 t9 i
通用方法(针对非COM数据类型)
( G: k0 d- p$ J: l8 D用sprintf完成转换
9 _2 N* u" A" h# v# N3 Z  wchar  buffer[200];* C$ A2 f7 X# v: v/ n
char  c = '1';
+ X; t  W5 J6 i" s5 qint   i = 35;* f6 ]) f$ p1 ?- T5 w8 W* w) H
long  j = 1000;
5 k' [6 w2 T+ q& i' Ufloat f = 1.7320534f;
* S  Y. O3 e( b) i" v7 Wsprintf( buffer, "%c",c);
" k. d" a6 s# V' k* [' Xsprintf( buffer, "%d",i);
% z9 F$ {6 S; Usprintf( buffer, "%d",j);
% }/ g- T! t* Fsprintf( buffer, "%f",f);8 T1 r3 n7 `; E& d; m, @
' Y( _- u8 {; X3 F$ E5 N. g
二、字符串转换为其它数据类型9 v& V3 |/ f- }- h* t4 S% k# z
strcpy(temp,"123"); 8 H1 t% Y) j% J$ P% F1 T
" y+ ~# Y; A% |3 {/ y3 M  W+ Z8 D
短整型(int)  T. V- w3 r% T* |% D6 {0 m( n
i = atoi(temp); % C) w% P2 S" n
长整型(long)
1 }7 s1 j: ^2 u6 g8 N( Ml = atol(temp);
) |' g0 |* `% a- I1 B( i/ l0 S. q3 _: H浮点(double)
: U' v; }: I2 e; Bd = atof(temp); - z; x+ @9 n0 ?  q8 k
CString变量
$ p( L4 c+ M6 a0 F. {4 W5 l1 e9 A: F) OCString name = temp;
# S7 E- @) G! dBSTR变量 ; T2 D( q$ l9 e9 w* V- i! t
BSTR bstrValue = ::SysAllocString(L"程序员"); % |- u8 t& f  k2 b
...///完成对bstrValue的使用
( \. _5 M; R+ `: n8 uSysFreeString(bstrValue);
" G5 T: |- w" M' O* g9 [8 E) k3 P7 j- L
CComBSTR变量2 _# w  @) }; M4 |+ b3 n
CComBSTR类型变量可以直接赋值3 I( F/ \: s! S
CComBSTR bstrVar1("test");
6 z/ ?" }" M# _  I1 `  N1 \CComBSTR bstrVar2(temp);( U) j3 o: h& T1 ~# V4 B
6 d  d% O) V" }/ @$ A1 |6 |
_bstr_t变量* I: ^' s" f9 `) K+ l( R+ W) w
_bstr_t类型的变量可以直接赋值1 y8 l) c* X, b
_bstr_t bstrVar1("test"); 6 q/ q* R/ E3 @$ |! K
_bstr_t bstrVar2(temp); 6 C" @3 e. j4 K9 ?& z/ K
; G! i4 {  d8 i

# W: ~, s) a; `三、其它数据类型转换到CString; a" M9 G5 e% _+ _! ?! c' e
使用CString的成员函数Format来转换,例如:
9 _& B1 R  }7 }- Y8 d+ `
- }$ |3 Y6 c* ?5 z: O
% @( c* _: r; P* _( p整数(int)
$ ~4 h# w' J! Q; E  _str.Format("%d",i);
/ U1 h& ?; Z) @, m9 @+ M浮点数(float)6 Q& F& g( ^# ?  {% Q
str.Format("%f",i); $ {+ X. q& _8 X# b
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
" i, z: Q8 b+ V7 s& Nstr = username; . D" D( u) ~+ u$ @
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
! X: R, j0 j- {, `& ^) j2 y. i
2 O1 c; u) v  e% }5 }' N4 z四、BSTR、_bstr_t与CComBSTR
4 m: N8 p! b* _( M! r" N4 v6 v) Z2 I) E' H+ |' J: o
8 W- X/ K: U: b
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。) C1 B3 l! P6 L) C2 x
char *转换到BSTR可以这样: ' c! }6 I! s0 Y1 [! y) x9 {8 Y4 y
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
3 Q3 i/ H0 C3 z5 u% F' N3 ?3 cSysFreeString(bstrValue); - i6 ^- s1 g' l, B; B
反之可以使用# @/ J) n7 N' R: q
char *p=_com_util::ConvertBSTRToString(b);/ R4 W! D) M1 q. M: Z& m7 W: d# N& x
delete p;( G0 j9 W% h& Z( m: W! x+ n
具体可以参考一,二段落里的具体说明。
+ H- {# O% J( J" A8 z3 I# G5 [5 [- W: O" w9 j7 N
CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
; l) O" y9 Z$ m6 t特别是_bstr_t,建议大家使用它。
. e4 K& `% H: t7 d: u
  ]3 f# k" i4 G+ ]4 S: @% B0 W
" i& O3 I( Q+ v2 B, S五、VARIANT 、_variant_t 与 COleVariant
$ b5 [% ^$ L0 a8 O6 S) S% N5 h' s$ Z/ S: j7 P( n, y
# z4 R3 r& g8 T$ C( J) P# A
VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。1 g: |4 R" l6 W
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:7 C" i% v2 w: {& {
VARIANT va;5 A  s( f5 H1 p0 o2 y/ g
int a=2001;
+ l& G2 V# \9 }$ e9 q4 l: Lva.vt=VT_I4;///指明整型数据
& y3 v2 R$ Z9 H. ~3 `/ Qva.lVal=a; ///赋值
7 D0 _! i8 k! \; {3 h7 p7 O2 M  l# \: V, R+ b
对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:- Y% N+ b! ?5 m+ d1 I7 a

. F$ _- {4 h6 p' [7 b  YByte bVal;  // VT_UI1.
" a# O9 Q8 B6 _! Z% w% I# EShort iVal;  // VT_I2. 2 L6 B4 D1 i, i; N
long lVal;  // VT_I4. 9 Z: ?" t2 G1 P
float fltVal;  // VT_R4. ( R9 ]+ e- {" y8 I2 p* W8 `0 I5 W
double dblVal;  // VT_R8.
$ y2 t2 F0 F% ~; k2 `VARIANT_BOOL boolVal;  // VT_BOOL. 3 X# H6 v& e- j2 N
SCODE scode;  // VT_ERROR.
; p& |' O. n$ @: bCY cyVal;  // VT_CY.
4 n  i, f2 g6 [2 @DATE date;  // VT_DATE.
* F2 Q6 }+ q* k' A) GBSTR bstrVal;  // VT_BSTR.
: a" ?( U2 \5 zDECIMAL FAR* pdecVal  // VT_BYREF|VT_DECIMAL. , O0 l& S( Z6 O3 {& K: j7 b2 J0 Z" p1 L
IUnknown FAR* punkVal;  // VT_UNKNOWN. 4 h- f; Z- B  w, G4 x& l5 o
IDispatch FAR* pdispVal;  // VT_DISPATCH.
5 ^$ g9 V  J& P0 ISAFEARRAY FAR* parray;  // VT_ARRAY|*. : Q* J2 Q9 t8 m" i" b
Byte FAR* pbVal;  // VT_BYREF|VT_UI1. ! a% V' |$ K+ V3 z
short FAR* piVal;  // VT_BYREF|VT_I2.
* X% M7 N' T. R0 nlong FAR* plVal;  // VT_BYREF|VT_I4. 7 _) f' P# n% K$ C, E, C
float FAR* pfltVal;  // VT_BYREF|VT_R4. - {& j. M+ d9 X2 O3 p: a
double FAR* pdblVal;  // VT_BYREF|VT_R8. # [1 ^. l) w0 }8 E7 K" I5 c
VARIANT_BOOL FAR* pboolVal;  // VT_BYREF|VT_BOOL. - ~# F& e' {# _! W3 v- n$ D4 N: r- z
SCODE FAR* pscode;  // VT_BYREF|VT_ERROR. , s' f& w& O, ?9 ?8 E/ Z( J6 N
CY FAR* pcyVal;  // VT_BYREF|VT_CY. / e: s1 O. q" Z3 u! b: N( h% @1 j3 C! |
DATE FAR* pdate;  // VT_BYREF|VT_DATE. 1 ?/ W4 z: ?: R' o0 L9 G
BSTR FAR* pbstrVal;  // VT_BYREF|VT_BSTR. : T" Y$ v. P6 ?' f5 L# `9 f
IUnknown FAR* FAR* ppunkVal;  // VT_BYREF|VT_UNKNOWN. + N+ k* }$ z- {
IDispatch FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.
% I+ O' X9 r% i7 {* a7 MSAFEARRAY FAR* FAR* pparray;  // VT_ARRAY|*. & q& {* T" |+ X, O/ O
VARIANT FAR* pvarVal;  // VT_BYREF|VT_VARIANT.
- d8 A, x1 v5 l/ a! Dvoid FAR* byref;  // Generic ByRef.
  V; k  W$ c# W* ~$ w1 @: {5 tchar cVal;  // VT_I1. ( k- ]; R8 l7 q; u1 m1 m: e( o
unsigned short uiVal;  // VT_UI2.
1 M$ {5 L% x3 s9 W) Sunsigned long ulVal;  // VT_UI4.
" t; C+ R5 c- i' j, N+ Zint intVal;  // VT_INT. 6 K$ P/ m  s" M  W: K: h5 y
unsigned int uintVal;  // VT_UINT.
3 {9 D+ _5 E8 j) w/ Zchar FAR * pcVal;  // VT_BYREF|VT_I1.
& }, x5 d/ T- ?) l+ w& Qunsigned short FAR * puiVal;  // VT_BYREF|VT_UI2. & A8 w3 \1 e3 n/ K7 X
unsigned long FAR * pulVal;  // VT_BYREF|VT_UI4.   J1 h4 q# \( S! a6 Z9 R# b) ]" Q: j
int FAR * pintVal;  // VT_BYREF|VT_INT. 0 F3 [: N7 d' _
unsigned int FAR * puintVal;  //VT_BYREF|VT_UINT.
& F- P3 Y* e- \% V' M: A
/ d' \. c# h. ^, }. h& P  L9 B
5 }5 I4 l6 d8 Q+ W_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
+ `9 D. G* N: S. i6 x- C使用时需加上#include <comdef.h>5 d5 S3 u* x: k, Y) S- i, e5 Y
例如:0 D" }2 v; l/ _  l) w; W5 S
long l=222;* C6 `$ t$ }2 L
ing i=100;
$ r; q6 @. A* {+ z; x# ~, f_variant_t lVal(l);
' A/ R2 X! R6 ~% E; d( j; mlVal = (long)i;
# Q* x2 i8 u, [) _$ F! A: C" I7 ?/ Y

. Z( v$ x0 _9 ~/ J/ o: X1 }0 mCOleVariant的使用与_variant_t的方法基本一样,请参考如下例子:, D0 I% \3 B3 |
COleVariant v3 = "字符串", v4 = (long)1999;
3 n) N. I7 w, c3 Y/ U$ KCString str =(BSTR)v3.pbstrVal;- P, H9 t& j$ N6 v1 _8 L8 L
long i = v4.lVal;: B- a8 K$ L  a, D! ~

$ V3 F  h6 J2 v2 F. G# S8 i3 E% e4 i
六、其它一些COM数据类型1 r+ Q' O. f0 G- R

9 D4 T# s8 ]8 U# s! D# [根据ProgID得到CLSID
* l; o& X3 p4 g; k9 qHRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
% S' i( b) ?$ w  _2 v5 N" A' QCLSID clsid;4 }7 y0 J! [' H, G# s4 [5 Q
CLSIDFromProgID( L"MAPI.Folder",&clsid);8 y; I2 g; b0 [0 L( x% g

" u( r$ c7 e" F) [2 H根据CLSID得到ProgID
! Y8 u+ Z0 a8 s4 E( O* V$ n1 c1 \1 GWINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); 5 F* t1 ?8 F  N# c8 T
例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
4 V3 C/ q: q" Q- @3 ^6 rLPOLESTR pProgID = 0;
7 x% s8 x3 H0 g3 KProgIDFromCLSID( CLSID_IApplication,&pProgID);$ \& W. O8 U2 }8 j  R% Q$ h
...///可以使用pProgID " A2 I2 `$ O) ?: z, q
CoTaskMemFree(pProgID);//不要忘记释放 . X) u4 A* Y+ s# J; e/ y( ~6 K& ?

1 T9 H% |; T/ w七、ANSI与Unicode4 S7 ^- h0 V$ u6 U: W0 ~
Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。
5 I7 ]% v& `! g/ c8 F  O& P. O1 B* L9 {% F3 _! G5 F
将ANSI转换到Unicode! p9 ~% g: ~- i- r
(1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
: [3 v5 m0 ~  [) Y+ {(2)通过MultiByteToWideChar函数实现转换,例如:+ \  j0 W! Y. {( A( e
char *szProgID = "MAPI.Folder";0 W% n( \5 L" @' r$ D7 o4 Q
WCHAR szWideProgID[128];: l" C7 D3 |* |- E  v! n3 ]
CLSID clsid;0 g& ^+ _  }* n1 t1 T& w% a
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));7 A2 _" m: \9 n
szWideProgID[lLen] = '\0'; ) r2 B( E7 p! L; \
(3)通过A2W宏来实现,例如:
5 n8 j# V- q5 y3 {$ W# RUSES_CONVERSION; 5 A- Q8 \/ @, N# |8 C
CLSIDFromProgID( A2W(szProgID),&clsid);
/ T: X6 K1 l5 w8 V3 ^$ E* e将Unicode转换到ANSI( ~: e! J8 K* ~
(1)使用WideCharToMultiByte,例如:0 o4 c% A4 g7 c3 O$ N* y
// 假设已经有了一个Unicode 串 wszSomeString... ! V' B. i6 f! d6 F) b  {
char szANSIString [MAX_PATH]; 3 l8 }7 m7 ~9 @
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
0 ^- F+ J; Y  B+ j(2)使用W2A宏来实现,例如:- p$ r* q% `# W9 x
USES_CONVERSION;
% p; N! \! w) M8 a/ gpTemp=W2A(wszSomeString);
  W; I( c4 I' f: ~' W2 x7 Q八、其它
# J5 l- A* ^! r& x* w
& J3 R# L" @6 ]  L1 S) p对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
. P! x, P- [) dLPARAM lParam;
: J: j" R% G  [& iWORD loValue = LOWORD(lParam);///取低16位
% F; c6 D; m$ r, gWORD hiValue = HIWORD(lParam);///取高16位
- v' r) ~& ?& V* N/ \3 Q( ~6 |0 D) }3 a( B! J
+ v, w$ v. M$ U3 ~4 m8 ~3 S1 O
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
3 y& G6 B+ ]$ c* D/ {% lWORD wValue;
% W8 p; g/ D7 G  I5 j0 xBYTE loValue = LOBYTE(wValue);///取低8位
3 P- n" l+ {9 b6 E) xBYTE hiValue = HIBYTE(wValue);///取高8位. e# N4 j1 J* k' M$ i

5 T5 M! U3 T6 n* l+ c- u) @3 \1 ^6 l; T1 ?; K% G
两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)7 b8 q" |, @9 c# p* B
LONG MAKELONG( WORD wLow, WORD wHigh );
$ _& S5 q" z8 x( R( D- hWPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); 9 t- T$ F9 U: u" S# ~8 B* U
LPARAM MAKELPARAM( WORD wLow, WORD wHigh );( R/ b9 l, O/ Q# Q
LRESULT MAKELRESULT( WORD wLow, WORD wHigh );
0 D# O+ L9 [) Q" k; b& P+ C" y1 }( U7 N
+ y: [, v) c) \! B" d& s% s! f2 I
两个8位的数据(BYTE)合成16位的数据(WORD)
, y5 T. I5 ?* D& n, D6 S/ b" RWORD MAKEWORD( BYTE bLow, BYTE bHigh );
# V* ^8 d5 B; h) {
! j; @: C6 Z7 N" ?, w6 m, E4 P, k& q7 \) z6 U- Y
从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
, X7 q' I/ C$ v! eCOLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
+ K+ x7 h  p/ t+ p: d/ M& S例如COLORREF bkcolor = RGB(0x22,0x98,0x34);: ], j, A+ Z( d8 v+ }
$ b3 k9 {% a$ l$ I# V; t4 |

+ ?+ M$ U- @7 r  s8 U从COLORREF类型的颜色值得到RGB三个颜色值7 `; _5 c$ F$ N) }) r( C* ^, j
BYTE Red = GetRValue(bkcolor); ///得到红颜色
. S* n, p  u: VBYTE Green = GetGValue(bkcolor); ///得到绿颜色2 _6 [/ n; b$ s2 @* I' a8 N
BYTE Blue = GetBValue(bkcolor); ///得到兰颜色
) z4 e; v( Z! `% y6 `% V0 H+ s0 s9 t$ I- N
九、注意事项
9 P5 V4 a! l% c: G8 I& Q假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )
1 W( v7 _+ S" W' R8 u
6 ?" F7 [& j( S' ]9 ^, ?0 |后记:本文匆匆写成,错误之处在所难免,欢迎指正.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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