VC++常用數據類型及其操作詳解(非常經典,共同分享)

友情提示:
爲了方便你更好的學習和閱讀,也更好的體現尊重原創作者的勞動成果,請您直接查看轉載原本鏈接:
===================================================================

VC++常用數據類型及其操作詳解

一.VC常用數據類型列表

二.常用數據類型轉化

2.1數學類型變量與字符串相互轉換

2.2 CString及string,char *與其他數據類型的轉換和操作

●CString,string,char*的綜合比較

●數學類型與CString相互轉化

●CString與char*相互轉換舉例

●CString 與 BSTR 型轉換

●VARIANT 型轉化成 CString 型

2.3 BSTR、_bstr_t與CComBSTR

2.4 VARIANT 、_variant_t 與 COleVariant

附錄CString及字符串轉及操作詳解

 

參考書籍:CSDN,<<MFC深入淺出(Second Edit)>>

 

                             一.VC常用數據類型列表

 

 

Type

Default Size

Description

 

 

 

 

 

 

說明:這些基礎數據類型對於MFC還是API都是被支持的

boolean

unsigned 8 bit ,

取值TRUE/FALSE

byte

unsigned 8 bit,

整數,輸出按字符輸出

char

unsigned 8 bit,

字符

double

signed 64 bit

浮點型

float

signed32 bit

浮點型

handle_t

 

Primitive handle type

hyper

signed 64 bit

整型

int

signed 32 bit

整型

long

signed 32 bit

整型

short

signed 16 bit

整型

small

signed 8 bit

整型

void *

32-bit

指向未知類型的指針

wchar_t

unsigned 16 bit

16位字符,比char可容納更多的字符

 

 

 

Win32

API

 

說明: 這些Win32API支持的簡單數據類型主要是用來定義函數返回值,消息參數,結構成員。這類數據類型大致可以分爲五大類:字符型、布爾型、整型、指針型和句柄型(?). 總共大概有100多種不同的類型

BOOL/BOOLEAN

8bit,TRUE/FALSE

布爾型

BYTE

unsigned 8 bit

 

BSTR

CComBSTR

_bstr_t

32 bit

BSTR是指向字符串的32位指針

是對BSTR的封裝

是對BSTR的封裝

CHAR

8 bit

(ANSI)字符類型

COLORREF

32 bit

RGB顏色值 整型

DWORD

unsigned 32 bit

整型

FLOAT

float型

float型

HANDLE

 

Object句柄

HBITMAP

 

bitmap句柄

HBRUSH

 

brush句柄

HCURSOR

 

cursor句柄

HDC

 

設備上下文句柄

HFILE

 

OpenFile打開的File句柄

HFONT

 

font句柄

HHOOK

 

hook句柄

HKEY

 

註冊表鍵句柄

HPEN

 

pen句柄

HWND

 

window句柄

INT

--------

--------

LONG

--------

---------

LONGLONG

 

64位帶符號整型

LPARAM

32 bit

消息參數

LPBOOL

 

BOOL型指針

LPBYTE

 

BYTE型指針

LPCOLOREF

 

COLORREF型指針

LPCSTR/LPSTR/PCSTR

 

指向8位(ANSI)字符串類型指針

LPCWSTR/LPWSTR/PCWSTR

 

指向16位Unicode字符串類型

LPCTSTR/LPTSTR/PCTSTR

 

指向一8位或16位字符串類型指針

LPVOID

 

指向一個未指定類型的32位指針

LPDWORD

 

指向一個DWORD型指針

其他相似類型: LPHANDLE、LPINT、LPLONG、LPWORD、LPRESULT

PBOOL、PBOOLEAN、PBYTE、PCHAR、PDWORD、PFLOAT、PHANDLE、PINT、PLONG、PSHORT……

說明:(1)在16位系統中 LP爲16bit,P爲8bit,在32位系統中都是32bit(此時等價)

(2)LPCSTR等 中的C指Const,T表示TCHAR模式即可以工作在ANSI下也可UNICODE

SHORT

usigned

整型

其他UCHAR、UINT、ULONG、ULONGLONG、USHORT爲無符號相應類型

TBYTE

 

WCHAR型或者CHAR型

TCHAR

 

ANSI與unicode均可

VARIANT

_variant_t

COleVariant

 

一個結構體參考OAIDL.H

_variant_t是VARIANT的封裝類

COleVariant也是VARIANT的封裝類

 

 

 

 

 

 

WNDPROC

 

指向一個窗口過程的32位指針

WCHAR

 

16位Unicode字符型

WORD

 

16位無符號整型

WPARAM

 

消息參數

MFC

獨有

數據

類型

下面兩個數據類型是微軟基礎類庫中獨有的數據類型

POSITION

標記集合中一個元素的位置的值,被MFC中的集合類所使用

LPCRECT

指向一個RECT結構體常量(不能修改)的32位指針

CString

其實是MFC中的一個類

 

 

 

說明:

(1)-------表示省略

(2)1Byte=8Bit,

字與機器有關,在8位系統中:字=1字節,16位系統中,1字=2字節,32位中:1字=4字節,

64位中1字=8字節.不要搞混這些概念.

 

 

二.常用數據類型轉化及操作

 

2.1 數學類型變量與字符串相互轉換(這些函數都在STDLIB.H裏)

(1)將數學類型轉換爲字符串可以用以下一些函數:

舉例: _CRTIMP char * __cdecl _itoa(int, char *, int);//這是一個將數字轉換爲一個字符串類型的函數,最後一個int表示轉換的進制

如以下程序:

int iTyep=3;

char *szChar;

itoa(iType,szChar,2);

cout<<szChar;//輸出爲1010

類似函數列表:

_CRTIMP char * __cdecl _itoa(int, char *, int);//爲了完整性,也列在其中

_CRTIMP char * __cdecl _ultoa(unsigned long, char *, int);

_CRTIMP char * __cdecl _ltoa(long, char *, int);

_CRTIMP char * __cdecl _i64toa(__int64, char *, int);

_CRTIMP char * __cdecl _ui64toa(unsigned __int64, char *, int);

_CRTIMP wchar_t * __cdecl _i64tow(__int64, wchar_t *, int);

_CRTIMP wchar_t * __cdecl _ui64tow(unsigned __int64, wchar_t *, int);

_CRTIMP wchar_t * __cdecl _itow (int, wchar_t *, int);//轉換爲長字符串類型

_CRTIMP wchar_t * __cdecl _ltow (long, wchar_t *, int);

_CRTIMP wchar_t * __cdecl _ultow (unsigned long, wchar_t *, int);

還有很多,請自行研究

 

(2)將字符串類型轉換爲數學類型變量可以用以下一些函數:

舉例: _CRTIMP int  __cdecl atoi(const char *);//參數一看就很明瞭

char *szChar=”88”;

int temp(0);

temp=atoi(szChar);

cout<<temp;

類似的函數列表:

_CRTIMP int    __cdecl atoi(const char *);

_CRTIMP double __cdecl atof(const char *);

_CRTIMP long   __cdecl atol(const char *);

_CRTIMP long double __cdecl _atold(const char *);

_CRTIMP __int64 __cdecl _atoi64(const char *);

_CRTIMP double __cdecl strtod(const char *, char **);//

_CRTIMP long   __cdecl strtol(const char *, char **, int);//

_CRTIMP long double __cdecl _strtold(const char *, char **);

_CRTIMP unsigned long __cdecl strtoul(const char *, char **, int);

_CRTIMP double __cdecl wcstod(const wchar_t *, wchar_t **);//長字符串類型轉換爲數學類型

_CRTIMP long   __cdecl wcstol(const wchar_t *, wchar_t **, int);

_CRTIMP unsigned long __cdecl wcstoul(const wchar_t *, wchar_t **, int);

_CRTIMP int __cdecl _wtoi(const wchar_t *);

_CRTIMP long __cdecl _wtol(const wchar_t *);

_CRTIMP __int64   __cdecl _wtoi64(const wchar_t *);

還有很多,請自行研究

 

2.2.CString及string,char *與其他數據類型的轉換和操作

(1)CString,string,char*的綜合比較(這部分CSDN上的作者joise的文章

<< CString,string,char*的綜合比較>>寫的很詳細,請大家在仔細閱讀他的文章.

地址: http://blog.csdn.net/joise/

或參考附錄:

 

 (2)轉換:

●數學類型與CString相互轉化

 數學類型轉化爲CString

可用Format函數,舉例:

CString s;

int i = 64;

s.Format("%d", i)

CString轉換爲數學類型:舉例CString strValue("1.234");

double dblValue;

dblValue = atof((LPCTSTR)strValue);

●CString與char*相互轉換舉例

CString strValue(“Hello”);

char *szValue;

szValue=strValue.GetBuffer(szValue);

也可用(LPSTR)(LPCTSTR)對CString //  進行強制轉換.  

szValue=(LPSTR)(LPCTSTR)strValue;

反過來可直接賦值:

char *szChar=NULL;

CString strValue;

szChar=new char[10];

memset(szChar,0,10);

strcpy(szChar,”Hello”);

strValue=szChar;

●CString 與 BSTR 型轉換

CString 型轉化成 BSTR 型

當我們使用 ActiveX 控件編程時,經常需要用到將某個值表示成 BSTR 類型.BSTR 是一種記數字符串,Intel平臺上的寬字符串(Unicode),並且可以包含嵌入的 NULL 字符。

可以調用 CString 對象的 AllocSysString 方法將 CString 轉化成 BSTR:

CString str;

str = .....; // whatever

BSTR bStr = str.AllocSysString();

 

BSTR型轉換爲CString

如果你在 UNICODE 模式下編譯代碼,你可以簡單地寫成:

CString convert(BSTR bStr)

{

    if(bStr == NULL)

        return CString(_T(""));

    CString s(bStr); // in UNICODE mode

    return s;

}

如果是 ANSI 模式

CString convert(BSTR b)

{

    CString s;

    if(b == NULL)

       return s; // empty for NULL BSTR

#ifdef UNICODE

    s = b;

#else

    LPSTR p = s.GetBuffer(SysStringLen(b) + 1);

    ::WideCharToMultiByte(CP_ACP,            // ANSI Code Page

                          0,                 // no flags

                          b,                 // source widechar string

                          -1,                // assume NUL-terminated

                          p,                 // target buffer

                          SysStringLen(b)+1, // target buffer length

                          NULL,              // use system default char

                          NULL);             // don''t care if default used

    s.ReleaseBuffer();

#endif

    return s;

}

 

●VARIANT 型轉化成 CString 型

VARIANT 類型經常用來給 COM 對象傳遞參數,或者接收從 COM 對象返回的值。你也能自己編寫返回 VARIANT 類型的方法,函數返回什麼類型 依賴可能(並且常常)方法的輸入參數(比如,在自動化操作中,依賴與你調用哪個方法。IDispatch::Invoke 可能返回(通過其一個參數)一個 包含有BYTE、WORD、float、double、date、BSTR 等等 VARIANT 類型的結果,(詳見 MSDN 上的 VARIANT 結構的定義)。在下面的例子中,假設 類型是一個BSTR的變體,也就是說在串中的值是通過 bsrtVal 來引用,其優點是在 ANSI 應用中,有一個構造函數會把 LPCWCHAR 引用的值轉換爲一個 CString(見 BSTR-to-CString 部分)。在 Unicode 模式中,將成爲標準的 CString 構造函數,參見對缺省::WideCharToMultiByte 轉換的告誡,以及你覺得是否可以接受(大多數情況下,你會滿意的)。VARIANT vaData;

vaData = m_com.YourMethodHere();

ASSERT(vaData.vt == VT_BSTR);

CString strData(vaData.bstrVal);

你還可以根據 vt 域的不同來建立更通用的轉換例程。爲此你可能會考慮:

CString VariantToString(VARIANT * va)

{

    CString s;

    switch(va->vt)

      { /* vt */

       case VT_BSTR:

          return CString(vaData->bstrVal);

       case VT_BSTR | VT_BYREF:

          return CString(*vaData->pbstrVal);

       case VT_I4:

          s.Format(_T("%d"), va->lVal);

          return s;

       case VT_I4 | VT_BYREF:

          s.Format(_T("%d"), *va->plVal);

       case VT_R8:

          s.Format(_T("%f"), va->dblVal);

          return s;

       ... 剩下的類型轉換由讀者自己完成

       default:

          ASSERT(FALSE); // unknown VARIANT type (this ASSERT is optional)

          return CString("");

      } /* vt */

}

 

2.3 BSTR、_bstr_t與CComBSTR

CComBSTR、_bstr_t是對BSTR的封裝,BSTR是指向字符串的32位指針。

char *轉換到BSTR可以這樣:

BSTR b=_com_util::ConvertStringToBSTR("數據");///使用前需要加上頭文件comutil.h

反之可以使用char *p=_com_util::ConvertBSTRToString(b);

 

2.4(引)VARIANT 、_variant_t 與 COleVariant

VARIANT的結構可以參考頭文件VC98/Include/OAIDL.H中關於結構體tagVARIANT的定義。

對於VARIANT變量的賦值:首先給vt成員賦值,指明數據類型,再對聯合結構中相同數據類型的變量賦值,舉個例子:

VARIANT va;

int a=2001;

va.vt=VT_I4;///指明整型數據

va.lVal=a; ///賦值

對於不馬上賦值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);進行初始化,其本質是將vt設置爲VT_EMPTY,下表我們列舉vt與常用數據的對應關係:

unsigned char bVal; VT_UI1

short iVal; VT_I2

long lVal; VT_I4

float fltVal; VT_R4

double dblVal; VT_R8

VARIANT_BOOL boolVal; VT_BOOL

SCODE scode; VT_ERROR

CY cyVal; VT_CY

DATE date; VT_DATE

BSTR bstrVal; VT_BSTR

IUnknown FAR* punkVal; VT_UNKNOWN

IDispatch FAR* pdispVal; VT_DISPATCH

SAFEARRAY FAR* parray; VT_ARRAY|*

unsigned char FAR* pbVal; VT_BYREF|VT_UI1

short FAR* piVal; VT_BYREF|VT_I2

long FAR* plVal; VT_BYREF|VT_I4

float FAR* pfltVal; VT_BYREF|VT_R4

double FAR* pdblVal; VT_BYREF|VT_R8

VARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL

SCODE FAR* pscode; VT_BYREF|VT_ERROR

CY FAR* pcyVal; VT_BYREF|VT_CY

DATE FAR* pdate; VT_BYREF|VT_DATE

BSTR FAR* pbstrVal; VT_BYREF|VT_BSTR

IUnknown FAR* FAR* ppunkVal; VT_BYREF|VT_UNKNOWN

IDispatch FAR* FAR* ppdispVal; VT_BYREF|VT_DISPATCH

SAFEARRAY FAR* FAR* pparray; VT_ARRAY|*

VARIANT FAR* pvarVal; VT_BYREF|VT_VARIANT

void FAR* byref; VT_BYREF

_variant_t是VARIANT的封裝類,其賦值可以使用強制類型轉換,其構造函數會自動處理這些數據類型。

例如:

long l=222;

ing i=100;

_variant_t lVal(l);

lVal = (long)i;

COleVariant的使用與_variant_t的方法基本一樣,請參考如下例子:

COleVariant v3 = "字符串", v4 = (long)1999;

CString str =(BSTR)v3.pbstrVal;

long i = v4.lVal;


 一、BSTR、LPSTR和LPWSTR 

  在Visual C++.NET的所有編程方式中,我們常常要用到這樣的一些基本字符串類型,如BSTR、LPSTR和LPWSTR等。之所以出現類似上述的這些數據類型,是因爲不同編程語言之間的數據交換以及對ANSI、Unicode和多字節字符集(MBCS)的支持。 

  那麼什麼是BSTR、LPSTR以及LPWSTR呢? 

  BSTR(Basic STRing,Basic字符串)是一個OLECHAR*類型的Unicode字符串。它被描述成一個與自動化相兼容的類型。由於操作系統提供相應的 API函數(如SysAllocString)來管理它以及一些默認的調度代碼,因此BSTR實際上就是一個COM字符串,但它卻在自動化技術以外的多種場合下得到廣泛使用。圖1描述了BSTR的結構,其中DWORD值是字符串中實際所佔用的字節數,且它的值是字符串中Unicode字符的兩倍。 

  LPSTR和LPWSTR是Win32和VC++所使用的一種字符串數據類型。LPSTR被定義成是一個指向以NULL(‘/0’)結尾的8位ANSI 字符數組指針,而LPWSTR是一個指向以NULL結尾的16位雙字節字符數組指針。在VC++中,還有類似的字符串類型,如LPTSTR、 LPCTSTR等,它們的含義如圖2所示。 

  例如,LPCTSTR是指“long pointer to a constant generic string”,表示“一個指向一般字符串常量的長指針類型”,與C/C++的const char*相映射,而LPTSTR映射爲 char*。 

  一般地,還有下列類型定義: 

#ifdef UNICODE 
 typedef LPWSTR LPTSTR; 
 typedef LPCWSTR LPCTSTR; 
#else 
 typedef LPSTR LPTSTR; 
 typedef LPCSTR LPCTSTR; 
#endif 


  二、CString、CStringA 和 CStringW 

  Visual C++.NET中將CStringT作爲ATL和MFC的共享的“一般”字符串類,它有CString、CStringA和CStringW三種形式,分別操作不同字符類型的字符串。這些字符類型是TCHAR、char和wchar_t。TCHAR在Unicode平臺中等同於WCHAR(16位 Unicode字符),在ANSI中等價於char。wchar_t通常定義爲unsigned short。由於CString在MFC應用程序中經常用到,這裏不再重複。 

  三、VARIANT、COleVariant 和_variant_t 

  在OLE、ActiveX和COM中,VARIANT數據類型提供了一種非常有效的機制,由於它既包含了數據本身,也包含了數據的類型,因而它可以實現各種不同的自動化數據的傳輸。下面讓我們來看看OAIDL.H文件中VARIANT定義的一個簡化版: 

struct tagVARIANT { 
 VARTYPE vt; 
 union { 
  short iVal;   // VT_I2. 
  long lVal;    // VT_I4. 
  float fltVal;  // VT_R4. 
  double dblVal; // VT_R8. 
  DATE date;     // VT_DATE. 
  BSTR bstrVal; // VT_BSTR. 
  … 
  short * piVal;  // VT_BYREF|VT_I2. 
  long * plVal;   // VT_BYREF|VT_I4. 
  float * pfltVal; // VT_BYREF|VT_R4. 
  double * pdblVal; // VT_BYREF|VT_R8. 
  DATE * pdate;     // VT_BYREF|VT_DATE. 
  BSTR * pbstrVal; // VT_BYREF|VT_BSTR. 
 }; 
}; 

  顯然,VARIANT類型是一個C結構,它包含了一個類型成員vt、一些保留字節以及一個大的union類型。例如,如果vt爲VT_I2,那麼我們可以從iVal中讀出VARIANT的值。同樣,當給一個VARIANT變量賦值時,也要先指明其類型。例如: 

VARIANT va; 
:: VariantInit(&va); // 初始化 
int a = 2002; 
va.vt = VT_I4; // 指明long數據類型 
va.lVal = a; // 賦值 

  爲了方便處理VARIANT類型的變量,Windows還提供了這樣一些非常有用的函數: 

  VariantInit —— 將變量初始化爲VT_EMPTY; 

  VariantClear —— 消除並初始化VARIANT; 

  VariantChangeType —— 改變VARIANT的類型; 

  VariantCopy —— 釋放與目標VARIANT相連的內存並複製源VARIANT。 

  COleVariant類是對VARIANT結構的封裝。它的構造函數具有極爲強大大的功能,當對象構造時首先調用VariantInit進行初始化,然後根據參數中的標準類型調用相應的構造函數,並使用VariantCopy進行轉換賦值操作,當VARIANT對象不在有效範圍時,它的析構函數就會被自動調用,由於析構函數調用了VariantClear,因而相應的內存就會被自動清除。除此之外,COleVariant的賦值操作符在與VARIANT類型轉換中爲我們提供極大的方便。例如下面的代碼: 

COleVariant v1("This is a test"); // 直接構造 
COleVariant v2 = "This is a test"; 
// 結果是VT_BSTR類型,值爲"This is a test" 
COleVariant v3((long)2002); 
COleVariant v4 = (long)2002; 
// 結果是VT_I4類型,值爲2002 

  _variant_t是一個用於COM的VARIANT類,它的功能與COleVariant相似。不過在Visual C++.NET的MFC應用程序中使用時需要在代碼文件前面添加下列兩句: 

  #include "comutil.h" 

  #pragma comment( lib, "comsupp.lib" )


    四、CComBSTR和_bstr_t 

  CComBSTR是對BSTR數據類型封裝的一個ATL類,它的操作比較方便。例如: 

CComBSTR bstr1; 
bstr1 = "Bye"; // 直接賦值 
OLECHAR* str = OLESTR("ta ta"); // 長度爲5的寬字符 
CComBSTR bstr2(wcslen(str)); // 定義長度爲5 
wcscpy(bstr2.m_str, str); // 將寬字符串複製到BSTR中 
CComBSTR bstr3(5, OLESTR("Hello World")); 
CComBSTR bstr4(5, "Hello World"); 
CComBSTR bstr5(OLESTR("Hey there")); 
CComBSTR bstr6("Hey there"); 
CComBSTR bstr7(bstr6); 
// 構造時複製,內容爲"Hey there" 

  _bstr_t是是C++對BSTR的封裝,它的構造和析構函數分別調用SysAllocString和SysFreeString函數,其他操作是借用BSTR API函數。與_variant_t相似,使用時也要添加comutil.h和comsupp.lib。 

  五、BSTR、char*和CString轉換 

  (1) char*轉換成CString 

  若將char*轉換成CString,除了直接賦值外,還可使用CString::Format進行。例如: 

char chArray[] = "This is a test"; 
char * p = "This is a test"; 

  或 

LPSTR p = "This is a test"; 

  或在已定義Unicode應的用程序中 

TCHAR * p = _T("This is a test"); 

  或 

LPTSTR p = _T("This is a test"); 
CString theString = chArray; 
theString.Format(_T("%s"), chArray); 
theString = p; 

  (2) CString轉換成char* 

若將CString類轉換成char*(LPSTR)類型,常常使用下列三種方法: 

方法一,使用強制轉換。例如: 
CString theString( "This is a test" ); 
LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString; 

方法二,使用strcpy。例如: 
CString theString( "This is a test" ); 
LPTSTR lpsz = new TCHAR[theString.GetLength()+1]; 
_tcscpy(lpsz, theString); 

  需要說明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二個參數是 const wchar_t* (Unicode)或const char* (ANSI),系統編譯器將會自動對其進行轉換。 

方法三,使用CString::GetBuffer。例如: 
CString s(_T("This is a test ")); 
LPTSTR p = s.GetBuffer(); 
// 在這裏添加使用p的代碼 
if(p != NULL) *p = _T('/0'); 
s.ReleaseBuffer(); 
// 使用完後及時釋放,以便能使用其它的CString成員函數 

  (3) BSTR轉換成char* 

方法一,使用ConvertBSTRToString。例如: 
#include 
#pragma comment(lib, "comsupp.lib") 
int _tmain(int argc, _TCHAR* argv[]){ 
BSTR bstrText = ::SysAllocString(L"Test"); 
char* lpszText2 = _com_util::ConvertBSTRToString(bstrText); 
SysFreeString(bstrText); // 用完釋放 
delete[] lpszText2; 
return 0; 


  方法二,使用_bstr_t的賦值運算符重載。例如: 

_bstr_t b = bstrText; 
char* lpszText2 = b; 

  (4) char*轉換成BSTR 

方法一,使用SysAllocString等API函數。例如: 
BSTR bstrText = ::SysAllocString(L"Test"); 
BSTR bstrText = ::SysAllocStringLen(L"Test",4); 
BSTR bstrText = ::SysAllocStringByteLen("Test",4); 

方法二,使用COleVariant或_variant_t。例如: 
//COleVariant strVar("This is a test"); 
_variant_t strVar("This is a test"); 
BSTR bstrText = strVar.bstrVal; 

方法三,使用_bstr_t,這是一種最簡單的方法。例如: 
BSTR bstrText = _bstr_t("This is a test"); 

方法四,使用CComBSTR。例如: 
BSTR bstrText = CComBSTR("This is a test"); 
或 
CComBSTR bstr("This is a test"); 
BSTR bstrText = bstr.m_str; 

方法五,使用ConvertStringToBSTR。例如: 
char* lpszText = "Test"; 
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText); 

  (5) CString轉換成BSTR 

  通常是通過使用CStringT::AllocSysString來實現。例如: 

CString str("This is a test"); 
BSTR bstrText = str.AllocSysString(); 
… 
SysFreeString(bstrText); // 用完釋放 

  (6) BSTR轉換成CString 

  一般可按下列方法進行: 

BSTR bstrText = ::SysAllocString(L"Test"); 
CStringA str; 
str.Empty(); 
str = bstrText; 

  或 

CStringA str(bstrText); 

  (7) ANSI、Unicode和寬字符之間的轉換 

  方法一,使用MultiByteToWideChar將ANSI字符轉換成Unicode字符,使用WideCharToMultiByte將Unicode字符轉換成ANSI字符。 

  方法二,使用“_T”將ANSI轉換成“一般”類型字符串,使用“L”將ANSI轉換成Unicode,而在託管C++環境中還可使用S將ANSI字符串轉換成String*對象。例如: 
TCHAR tstr[] = _T("this is a test"); 
wchar_t wszStr[] = L"This is a test"; 
String* str = S”This is a test”; 

  方法三,使用ATL 7.0的轉換宏和類。ATL7.0在原有3.0基礎上完善和增加了許多字符串轉換宏以及提供相應的類,它具有如圖3所示的統一形式: 
  其中,第一個C表示“類”,以便於ATL 3.0宏相區別,第二個C表示常量,2表示“to”,EX表示要開闢一定大小的緩衝。SourceType和DestinationType可以是A、 T、W和OLE,其含義分別是ANSI、Unicode、“一般”類型和OLE字符串。例如,CA2CT就是將ANSI轉換成一般類型的字符串常量。下面是一些示例代碼: 
LPTSTR tstr= CA2TEX<16>("this is a test"); 
LPCTSTR tcstr= CA2CT("this is a test"); 
wchar_t wszStr[] = L"This is a test"; 
char* chstr = CW2A(wszStr); 

  六、結語

幾乎所有的程序都要用到字符串,而Visual C++.NET由於功能強大、應用廣泛,因而字符串之間的轉換更爲頻繁。本文幾乎涉及到目前的所有轉換方法。當然對於.NET框架來說,還可使用Convert和Text類進行不同數據類型以及字符編碼之間的相互轉換。

int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="程佩君";
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;


一、其它數據類型轉換爲字符串

 

  • 短整型(int)
    itoa(i,temp,10);///將i轉換爲字符串放入temp中,最後一個數字表示十進制
    itoa(i,temp,2); ///按二進制方式轉換
  • 長整型(long)
    ltoa(l,temp,10);
  • 浮點數(float,double)
    用fcvt可以完成轉換,這是MSDN中的例子:
    int decimal, sign; 
    char *buffer; 
    double source = 3.1415926535; 
    buffer = _fcvt( source, 7, &decimal, &sign ); 
    運行結果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
    decimal表示小數點的位置,sign表示符號:0爲正數,1爲負數
  • CString變量
    str = "2008北京奧運";
    buf = (LPSTR)(LPCTSTR)str;
  • BSTR變量
    BSTR bstrValue = ::SysAllocString(L"程序員"); 
    char * buf = _com_util::ConvertBSTRToString(bstrValue); 
    SysFreeString(bstrValue); 
    AfxMessageBox(buf); 
    delete(buf);
  • CComBSTR變量
    CComBSTR bstrVar("test"); 
    char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str); 
    AfxMessageBox(buf); 
    delete(buf);
  • _bstr_t變量
    _bstr_t類型是對BSTR的封裝,因爲已經重載了=操作符,所以很容易使用
    _bstr_t bstrVar("test"); 
    const char *buf = bstrVar;///不要修改buf中的內容 
    AfxMessageBox(buf);
  • 通用方法(針對非COM數據類型)
    用sprintf完成轉換
    char  buffer[200];char  c = '1';int   i = 35;long  j = 1000;float f = 1.7320534f;sprintf( buffer, "%c",c);sprintf( buffer, "%d",i);sprintf( buffer, "%d",j);sprintf( buffer, "%f",f);

二、字符串轉換爲其它數據類型
strcpy(temp,"123");

  • 短整型(int)
    i = atoi(temp);
  • 長整型(long)
    l = atol(temp);
  • 浮點(double)
    d = atof(temp);
  • CString變量
    CString name = temp;
  • BSTR變量 
    BSTR bstrValue = ::SysAllocString(L"程序員"); 
    ...///完成對bstrValue的使用
    SysFreeString(bstrValue);
  • CComBSTR變量
    CComBSTR類型變量可以直接賦值
    CComBSTR bstrVar1("test");
    CComBSTR bstrVar2(temp);
  • _bstr_t變量
    _bstr_t類型的變量可以直接賦值
    _bstr_t bstrVar1("test"); 
    _bstr_t bstrVar2(temp);

三、其它數據類型轉換到CString
使用CString的成員函數Format來轉換,例如:

  • 整數(int)
    str.Format("%d",i);
  • 浮點數(float)
    str.Format("%f",i);
  • 字符串指針(char *)等已經被CString構造函數支持的數據類型可以直接賦值
    str = username;
  • 對於Format所不支持的數據類型,可以通過上面所說的關於其它數據類型轉化到char *的方法先轉到char *,然後賦值給CString變量。

四、BSTR、_bstr_t與CComBSTR

  • CComBSTR 是ATL對BSTR的封裝,_bstr_t是C++對BSTR的封裝,BSTR是32位指針,但並不直接指向字串的緩衝區。
    char *轉換到BSTR可以這樣: 
    BSTR b=_com_util::ConvertStringToBSTR("數據");///使用前需要加上comutil.h和comsupp.lib
    SysFreeString(bstrValue); 
    反之可以使用
    char *p=_com_util::ConvertBSTRToString(b);
    delete p;
    具體可以參考一,二段落裏的具體說明。

    CComBSTR與_bstr_t對大量的操作符進行了重載,可以直接進行=,!=,==等操作,所以使用非常方便。
    特別是_bstr_t,建議大家使用它。

五、VARIANT 、_variant_t 與 COleVariant

  • VARIANT的結構可以參考頭文件VC98/Include/OAIDL.H中關於結構體tagVARIANT的定義。
    對於VARIANT變量的賦值:首先給vt成員賦值,指明數據類型,再對聯合結構中相同數據類型的變量賦值,舉個例子:
    VARIANT va;
    int a=2001;
    va.vt=VT_I4;///指明整型數據
    va.lVal=a; ///賦值

    對於不馬上賦值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);進行初始化,其本質是將vt設置爲VT_EMPTY,下表我們列舉vt與常用數據的對應關係:

    Byte bVal; // VT_UI1.
    Short iVal; // VT_I2.
    long lVal; // VT_I4.
    float fltVal; // VT_R4.
    double dblVal; // VT_R8.
    VARIANT_BOOL boolVal; // VT_BOOL.
    SCODE scode; // VT_ERROR.
    CY cyVal; // VT_CY.
    DATE date; // VT_DATE.
    BSTR bstrVal; // VT_BSTR.
    DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL.
    IUnknown FAR* punkVal; // VT_UNKNOWN.
    IDispatch FAR* pdispVal; // VT_DISPATCH.
    SAFEARRAY FAR* parray; // VT_ARRAY|*.
    Byte FAR* pbVal; // VT_BYREF|VT_UI1.
    short FAR* piVal; // VT_BYREF|VT_I2.
    long FAR* plVal; // VT_BYREF|VT_I4.
    float FAR* pfltVal; // VT_BYREF|VT_R4.
    double FAR* pdblVal; // VT_BYREF|VT_R8.
    VARIANT_BOOL FAR* pboolVal; // VT_BYREF|VT_BOOL.
    SCODE FAR* pscode; // VT_BYREF|VT_ERROR.
    CY FAR* pcyVal; // VT_BYREF|VT_CY.
    DATE FAR* pdate; // VT_BYREF|VT_DATE.
    BSTR FAR* pbstrVal; // VT_BYREF|VT_BSTR.
    IUnknown FAR* FAR* ppunkVal; // VT_BYREF|VT_UNKNOWN.
    IDispatch FAR* FAR* ppdispVal; // VT_BYREF|VT_DISPATCH.
    SAFEARRAY FAR* FAR* pparray; // VT_ARRAY|*.
    VARIANT FAR* pvarVal; // VT_BYREF|VT_VARIANT.
    void FAR* byref; // Generic ByRef.
    char cVal; // VT_I1.
    unsigned short uiVal; // VT_UI2.
    unsigned long ulVal; // VT_UI4.
    int intVal; // VT_INT.
    unsigned int uintVal; // VT_UINT.
    char FAR * pcVal; // VT_BYREF|VT_I1.
    unsigned short FAR * puiVal; // VT_BYREF|VT_UI2.
    unsigned long FAR * pulVal; // VT_BYREF|VT_UI4.
    int FAR * pintVal; // VT_BYREF|VT_INT.
    unsigned int FAR * puintVal; //VT_BYREF|VT_UINT.
  • _variant_t是VARIANT的封裝類,其賦值可以使用強制類型轉換,其構造函數會自動處理這些數據類型。
    使用時需加上#include <comdef.h>
    例如:
    long l=222;
    ing i=100;
    _variant_t lVal(l);
    lVal = (long)i;
  • COleVariant的使用與_variant_t的方法基本一樣,請參考如下例子:
    COleVariant v3 = "字符串", v4 = (long)1999;
    CString str =(BSTR)v3.pbstrVal;
    long i = v4.lVal;

六、其它一些COM數據類型

  • 根據ProgID得到CLSID
    HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
    CLSID clsid;
    CLSIDFromProgID( L"MAPI.Folder",&clsid);
  • 根據CLSID得到ProgID
    WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); 
    例如我們已經定義了 CLSID_IApplication,下面的代碼得到ProgID
    LPOLESTR pProgID = 0;
    ProgIDFromCLSID( CLSID_IApplication,&pProgID);
    ...///可以使用pProgID 
    CoTaskMemFree(pProgID);//不要忘記釋放

七、ANSI與Unicode
Unicode稱爲寬字符型字串,COM裏使用的都是Unicode字符串。

  • 將ANSI轉換到Unicode
    (1)通過L這個宏來實現,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
    (2)通過MultiByteToWideChar函數實現轉換,例如:
    char *szProgID = "MAPI.Folder";
    WCHAR szWideProgID[128];
    CLSID clsid;
    long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
    szWideProgID[lLen] = '/0'; 
    (3)通過A2W宏來實現,例如: 
    USES_CONVERSION; 
    CLSIDFromProgID( A2W(szProgID),&clsid);
  • 將Unicode轉換到ANSI
    (1)使用WideCharToMultiByte,例如:
    // 假設已經有了一個Unicode 串 wszSomeString... 
    char szANSIString [MAX_PATH]; 
    WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); 
    (2)使用W2A宏來實現,例如:
    USES_CONVERSION;
    pTemp=W2A(wszSomeString);

八、其它

  • 對消息的處理中我們經常需要將WPARAM或LPARAM等32位數據(DWORD)分解成兩個16位數據(WORD),例如:
    LPARAM lParam;
    WORD loValue = LOWORD(lParam);///取低16位
    WORD hiValue = HIWORD(lParam);///取高16位
  • 對於16位的數據(WORD)我們可以用同樣的方法分解成高低兩個8位數據(BYTE),例如:
    WORD wValue;
    BYTE loValue = LOBYTE(wValue);///取低8位
    BYTE hiValue = HIBYTE(wValue);///取高8位
  • 兩個16位數據(WORD)合成32位數據(DWORD,LRESULT,LPARAM,或WPARAM)
    LONG MAKELONG( WORD wLow, WORD wHigh );
    WPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); 
    LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
    LRESULT MAKELRESULT( WORD wLow, WORD wHigh );
  • 兩個8位的數據(BYTE)合成16位的數據(WORD)
    WORD MAKEWORD( BYTE bLow, BYTE bHigh );
  • 從R(red),G(green),B(blue)三色得到COLORREF類型的顏色值
    COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
    例如COLORREF bkcolor = RGB(0x22,0x98,0x34);
  • 從COLORREF類型的顏色值得到RGB三個顏色值
    BYTE Red = GetRValue(bkcolor); ///得到紅顏色
    BYTE Green = GetGValue(bkcolor); ///得到綠顏色
    BYTE Blue = GetBValue(bkcolor); ///得到蘭顏色

九、注意事項
假如需要使用到ConvertBSTRToString此類函數,需要加上頭文件comutil.h,並在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )

後記:本文匆匆寫成,錯誤之處在所難免,歡迎指正.

關於把BSTR類型數據轉換成CString 類型數據時的問題?
當我在把BSTR類型數據轉換成CString 或 “char* 類型”數據時,發現在BSTR類型字符串較短的情況下沒問題,當較長時就會出現
內存讀寫錯了。(在NT,2000下都測試是這樣的。)
根據你所說:
1)字符串指針(char *)等已經被CString構造函數支持的數據類型 可以直接賦值 str = username;
2)當b 爲BSTR類型時可以使用
char *p=_com_util::ConvertBSTRToString(b);
於是以下是對的:
CString cstr;
BSTR bstr;
....
cstr=com_util::ConvertBSTRToString(bstr);
...
可是當bstr非常大時(其實,較大時就會)就會出現內存讀寫錯,不知何故。
此外我發現cstr=com_util::ConvertBSTRToString(bstr);
可以簡化爲 cstr=bstr; 但當bstr較大時同樣出現這個問題。
請兄弟幫忙!急。謝謝!

如何轉化((list*)fileip.bian)->liang

關於把CString轉化成LPCTSTR的問題 作者:jakiesun 發表日期:2001-9-5 20:08:48
我記的我以前寫過這樣一段代碼
void function()
{
CString str,str1,str2;
function((char*)(LPCTSTR)str1);
str=str1;
...//調試道此發現str2的值隨着str的改變而改變,請問能解釋一下爲什麼,如有回答,請通知
[email protected],tx先

}

添加lib支持 作者:磨刀霍霍 發表日期:2001-9-10 11:32:12
如果不添加會產生錯誤,在setting中加入comsupp.lib或者直接#pragma comment( lib, "comsupp.lib" )
微軟認爲缺省的設置call convention如果不設置成__cdecl也會出現同樣的錯誤。


1。int 轉成cstring ??

回覆人: caigzhi(caigzhi) (2001-10-17 11:27:35) 得0分 
CString 的成員函數Format()

int a = 2131;
CString str;
str.Format("%d",a);

回覆人: tenchi(C與C++之間) (2001-10-17 11:32:12) 得0分 
int i=2001;
char str[10];
_itoa(i,str,10);
CString szString=str; 
回覆人: fiolin(幽深的水) (2001-10-17 11:45:40) 得0分 
他們兩個的都可以!! 

回覆人: sohucsdnvc(thanks) (2001-10-17 13:24:17) 得0分 
那如何把double轉成cstring 
回覆人: yihugang(小虎子) (2001-10-17 13:29:15) 得6分 
int i = 2131;
char *c=new char[20];
CString str;
sprintf(c,'%d',i);
str=*c;


回覆人: Gu_c_h(Gu) (2001-10-17 14:07:17) 得0分 
用 _gcvt 下面是 msdn 的例子

Example

/* _GCVT.C: This program converts -3.1415e5
* to its string representation.
*/

#include <stdlib.h>
#include <stdio.h>

void main( void )
{
char buffer[50];
double source = -3.1415e5;
_gcvt( source, 7, buffer );
printf( "source: %f buffer: '%s'/n", source, buffer );
_gcvt( source, 7, buffer );
printf( "source: %e buffer: '%s'/n", source, buffer );
}


Output

source: -314150.000000 buffer: '-314150.'
source: -3.141500e+005 buffer: '-314150.'

回覆人: Gu_c_h(Gu) (2001-10-17 14:49:56) 得6分 
int a = -3.1415e5;
CString str;
str.Format("%f",a); 
回覆人: ruixp(銳劍) (2001-10-17 15:06:48) 得6分 
CString 的成員函數Format()
int a = 2131;
CString str;
str.Format("%d",a);

2。基類對象怎麼能轉換成派生類對象?
int CDaoListView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
lpCreateStruct->style |= LVS_REPORT |LVS_EDITLABELS;
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;

//////////// 創建ImageList;
CDaoViewApp * pApp = (CDaoViewApp *) AfxGetApp();

m_pImageList = new CImageList();
ASSERT(m_pImageList !=NULL);
m_pImageList->Create(16,16,TRUE,4,4);
m_pImageList->Add(pApp->LoadIcon(IDI_KEY));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON4));
m_pImageList->Add(pApp->LoadIcon(IDI_ICON5));

CListCtrlEx& ctlList = (CListCtrlEx&) GetListCtrl();//我不懂的就這句,cListCtrlEx看下面的聲明。
ctlList.SetImageList (m_pImageList, LVSIL_SMALL) ;
////////////
return 0;
}

class CListCtrlEx : public CListCtrl//類cListCtrlEx定義。
{.....
}
class CDaoListView : public CListView//cDaoListView定義!
{
...
}
注:我的問題是GetListCtrl()返回的是一個cListCtrl對象的引用,怎麼能把它轉換成一個它的派生類對象的引用?c++的類型轉換怎麼支持? 


回覆貼子: 
回覆人: lhj(努力加油) (2002-1-29 18:56:06) 得0分 
CListCtrlEx& ctlList = (CListCtrlEx&) GetListCtrl();
這是強制類型轉換,&表示是一個引用,lctList的值在這次賦值後不能被修改。

回覆人: wwwsq(wwwsq) (2002-1-29 19:09:22) 得0分 
建議你找本C++方面的書看看,VC雖然號稱可視,實際上C++基礎還是很重要的。


回覆人: xcopy(xcopy) (2002-1-29 19:26:16) 得0分 
用dynamic_cast()可以安全的轉換。 

3。如何在CString和double之間轉換?要求轉換之後能保留小數點,保留正負號??

cstring::format(%.xe) x爲精度位 

回覆人: pchaos(雜講) (2002-1-28 11:21:46) 得0分 
CString str;
double db;
str = "123.456";
db = atof((LPCTSTR)str); 
回覆人: hgw111(hg) (2002-1-28 11:52:57) 得0分 
CString -> double : atof
double ->CString :Format 
回覆人: pchaos(雜講) (2002-1-28 13:46:04) 得0分 
CString str;
double db;
str = "123.456";
db = atof((LPCTSTR)str); 
db = 777.999;
str.format("%e", db); 

4。字符型要轉換成int??
atoi(str) 

5。_bstr_t 到 unsigned int??
_bstr_t str;
unsigned int Length=6;
Length=Length-str.length(); 

6。VARIANT類型轉換問題?
我在使用MSCOMM中SetOutput()函數時
形參必須爲VARIANT變量
如何將其它的數據類型轉換爲VARIANT類型?
如:Cstring->VARIANT、 *char->VARIANT
我對VARIANT的類型結構體不太熟,請講詳細些(最好有範例),謝謝!

回覆貼子: 
回覆人: vc_xiaoxin(小新) (2001-12-26 15:43:57) 得0分 
VARIANT本身是一個複雜的結構,別的數據怎麼轉呀?關注 
回覆人: mpg_liu(星仁) (2001-12-27 18:33:50) 得10分 
定義一個VARIANT變量後,他應該是一個結構體變量,其中有一個成員是字符型的,給這個成員賦值 
回覆人: LLnju(LLnju) (2001-12-27 18:36:10) 得0分 
實在不清楚嘛就用 _variant_t , COleVariant 這些東東嘛,很好用的啊 
回覆人: softarts(CDMA2000) (2001-12-27 18:41:32) 得10分 
構造一個就行了。
VARIANT varXX;
CString strYY;
varXX.vt=VT_BSTR;
varXX.bstrVal = strYY.allocsysstring();
應該可以了。
回覆人: softarts(CDMA2000) (2001-12-27 18:42:11) 得0分 
我也覺得COleVariant要好用一些,呵呵,我都用它。 
回覆人: bobofu(有問題要問) (2001-12-27 19:32:18) 得10分 
CString str;
_variant_t var;
var = _variant_t(str); 

7。COleVarant 如何轉換爲 CString?
CString 如何轉換爲 char *
CString 如何轉換爲 char[xx] ??

CString 如何轉換爲 char * wsprintf或者=
CString 如何轉換爲 char[xx] strcpy() 
回覆人: SecretGarden(天堂鳥) (2002-1-14 11:55:23) 得0分 
COleVarant封裝了VAREANT類型。
VAREANT類型其實是個巨大地Union,裏面自然有你
想要地unsigned char *類型。
CString地GetBuffer和Format可以實現你的後兩個問題


8。v_variant_t類型轉換成cstring
總提示我cstring未定義
程序如下
_variant_t vfirstname;//存儲的是數據庫中的數據
CString str;//提示出錯
vfirstname=pRs->GetCollect (_variant_t("Phone_Num"));
vfirstname.ChangeType (VT_BSTR);
str=vfirstname.bstrVal;//提示出錯 


回覆貼子: 
回覆人: hydnoahark(諾亞方舟) (2001-11-12 11:56:51) 得10分 
>>CString str;//提示出錯
要求include <afx.h>並且設置Use run-time Library爲Multithreaded 
回覆人: zhengyun_ustc(^-^) (2001-11-12 12:04:39) 得15分 
CString未定義,說明你的工程沒有引用MFC!!

要想使你的工程支持MFC,請按照以下步驟作:
1:在你的stdafx.h的頭文件中加入:
#include "afxtempl.h"
這是一個囊括了MFC的集合定義的頭文件,有了它,你的工程就識別Cstring類了。

2:在你的工程設置中,在General頁中,選擇“MFC”爲“Using MFC in a shared DLL”

OK,現在再編譯你的工程即可。 
回覆人: zhengyun_ustc(^-^) (2001-11-12 12:06:56) 得5分 
_variant_t的bstrVal成員是BSTR類型。
它是一個指向一個OLECHART*的指針。 
回覆人: vickowang(小蒼) (2001-11-12 12:48:21) 得5分 
(char *)_bstr_t(vfirstname) 
回覆人: smallfool(smallfool) (2001-11-12 13:52:54) 得4分 
或許你還需要一個從UNICODE字符到ANSI字符的轉變函數 
回覆人: sun_1112(蕭) (2001-11-12 17:34:44) 得0分 
謝謝大家
給我這麼大的支持!:) 
回覆人: zhengyun_ustc(^-^) (2001-11-14 13:24:07) 得0分 
用vickowang(小蒼)的意見可能會有問題,轉換出的字符串應該是亂碼。

因爲(char *)轉換需要一個const的字符串資源,才能強制轉換。
所以應該:
_bstr_t bstrTemp = _bstr_t(vfirstname.bstrVal);
TCHAR szTemp[MAX_PATH];
szTemp = (char*)bstrTemp;

9。char * 轉換爲TCHAR類型??
直接轉換,TCHAR相當於char了
char * s;
TCHAR * s1=(TCHAR *)s; 
回覆人: dysxq() (2001-12-21 21:26:25) 得0分 
要看你的程序設置是ANSI還是UNICODE, 如果是ANSI,直接轉,如果是UNICODE,TCHAR相當於WCHAR, 要用mbstowcsz轉一下 
回覆人: xiaoxiaohan(蕭曉寒) (2001-12-21 23:52:17) 得0分 
Unicode :寬字節字符集
1. 如何取得一個既包含單字節字符又包含雙字節字符的字符串的字符個數?
可以調用Microsoft Visual C++的運行期庫包含函數_mbslen來操作多字節(既包括單字節也包括雙字節)字符串。
調用strlen函數,無法真正瞭解字符串中究竟有多少字符,它只能告訴你到達結尾的0之前有多少個字節。
2. 如何對DBCS(雙字節字符集)字符串進行操作?
函數 描述
PTSTR CharNext ( LPCTSTR ); 返回字符串中下一個字符的地址
PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一個字符的地址
BOOL IsDBCSLeadByte( BYTE ); 如果該字節是DBCS字符的第一個字節,則返回非0值
3. 爲什麼要使用Unicode?
(1) 可以很容易地在不同語言之間進行數據交換。
(2) 使你能夠分配支持所有語言的單個二進制.exe文件或DLL文件。
(3) 提高應用程序的運行效率。
Windows 2000是使用Unicode從頭進行開發的,如果調用任何一個Windows函數並給它傳遞一個ANSI字符串,那麼系統首先要將字符串轉換成
Unicode,然後將Unicode字符串傳遞給操作系統。如果希望函數返回ANSI字符串,系統就會首先將Unicode字符串轉換成ANSI字符串,然後將結
果返回給你的應用程序。進行這些字符串的轉換需要佔用系統的時間和內存。通過從頭開始用Unicode來開發應用程序,就能夠使你的應用程序
更加有效地運行。
Windows CE 本身就是使用Unicode的一種操作系統,完全不支持ANSI Windows函數
Windows 98 只支持ANSI,只能爲ANSI開發應用程序。
Microsoft公司將COM從16位Windows轉換成Win32時,公司決定需要字符串的所有COM接口方法都只能接受Unicode字符串。
4. 如何編寫Unicode源代碼?
Microsoft公司爲Unicode設計了WindowsAPI,這樣,可以儘量減少代碼的影響。實際上,可以編寫單個源代碼文件,以便使用或者不使用
Unicode來對它進行編譯。只需要定義兩個宏(UNICODE和_UNICODE),就可以修改然後重新編譯該源文件。
_UNICODE宏用於C運行期頭文件,而UNICODE宏則用於Windows頭文件。當編譯源代碼模塊時,通常必須同時定義這兩個宏。
5. Windows定義的Unicode數據類型有哪些?
數據類型 說明
WCHAR Unicode字符
PWSTR 指向Unicode字符串的指針
PCWSTR 指向一個恆定的Unicode字符串的指針
對應的ANSI數據類型爲CHAR,LPSTR和LPCSTR。
ANSI/Unicode通用數據類型爲TCHAR,PTSTR,LPCTSTR。
6. 如何對Unicode進行操作?
字符集 特性 實例
ANSI 操作函數以str開頭 strcpy
Unicode 操作函數以wcs開頭 wcscpy
MBCS 操作函數以_mbs開頭 _mbscpy
ANSI/Unicode 操作函數以_tcs開頭 _tcscpy(C運行期庫)
ANSI/Unicode 操作函數以lstr開頭 lstrcpy(Windows函數)
所有新的和未過時的函數在Windows2000中都同時擁有ANSI和Unicode兩個版本。ANSI版本函數結尾以A表示;Unicode版本函數結尾以W表示。
Windows會如下定義:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE
7. 如何表示Unicode字符串常量?
字符集 實例
ANSI “string”
Unicode L“string”
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }
8. 爲什麼應當儘量使用操作系統函數?
這將有助於稍稍提高應用程序的運行性能,因爲操作系統字符串函數常常被大型應用程序比如操作系統的外殼進程Explorer.exe所使用。由於
這些函數使用得很多,因此,在應用程序運行時,它們可能已經被裝入RAM。
如:StrCat,StrChr,StrCmp和StrCpy等。
9. 如何編寫符合ANSI和Unicode的應用程序?
(1) 將文本串視爲字符數組,而不是chars數組或字節數組。
(2) 將通用數據類型(如TCHAR和PTSTR)用於文本字符和字符串。
(3) 將顯式數據類型(如BYTE和PBYTE)用於字節、字節指針和數據緩存。
(4) 將TEXT宏用於原義字符和字符串。
(5) 執行全局性替換(例如用PTSTR替換PSTR)。
(6) 修改字符串運算問題。例如函數通常希望在字符中傳遞一個緩存的大小,而不是字節。這意味着不應該傳遞sizeof(szBuffer),而應該傳
遞(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要爲字符串分配一個內存塊,並且擁有該字符串中的字符數目,那麼請記住要按字節來
分配內存。這就是說,應該調用malloc(nCharacters *sizeof(TCHAR)),而不是調用malloc(nCharacters)。
10. 如何對字符串進行有選擇的比較?
通過調用CompareString來實現。
標誌 含義
NORM_IGNORECASE 忽略字母的大小寫
NORM_IGNOREKANATYPE 不區分平假名與片假名字符
NORM_IGNORENONSPACE 忽略無間隔字符
NORM_IGNORESYMBOLS 忽略符號
NORM_IGNOREWIDTH 不區分單字節字符與作爲雙字節字符的同一個字符
SORT_STRINGSORT 將標點符號作爲普通符號來處理
11. 如何判斷一個文本文件是ANSI還是Unicode?
判斷如果文本文件的開頭兩個字節是0xFF和0xFE,那麼就是Unicode,否則是ANSI。
12. 如何判斷一段字符串是ANSI還是Unicode?
用IsTextUnicode進行判斷。IsTextUnicode使用一系列統計方法和定性方法,以便猜測緩存的內容。由於這不是一種確切的科學方法,因此 
IsTextUnicode有可能返回不正確的結果。
13. 如何在Unicode與ANSI之間轉換字符串?
Windows函數MultiByteToWideChar用於將多字節字符串轉換成寬字符串;函數WideCharToMultiByte將寬字符串轉換成等價的多字節字符串。

回覆人: xtky_limi(痛在心中笑在臉上) (2001-12-22 0:35:58) 得0分 
上面說的已經比較全了。 
回覆人: xtky_limi(痛在心中笑在臉上) (2001-12-22 0:38:13) 得0分 
TEXT是宏
相當於L##

它可以根據編譯環境確定爲DBMS,還是UNICODE字符集

10。int類型轉換爲CString類型?
回覆人: tjmxf(天涯) (2001-12-17 19:59:34) 得0分 
itoa() 
回覆人: zf925(天下哪來那麼多高手) (2001-12-17 20:00:30) 得22分 
char m[20];
str=str + itoa(i,m,10); 
回覆人: yuezifeng(wybzd) (2001-12-17 20:00:50) 得22分 
CString str;
str.Format("%d",i);

回覆人: kingfish(今飛) (2001-12-17 20:06:27) 得0分 
str.Format("%s%d",str,i); 
回覆人: tanyajun(談子) (2001-12-17 20:09:25) 得0分 
CString str="test";
int i=11;
CString str1;
str1.Format("%d",i);
str = str+str1;

回覆人: guanjinke(綸巾客) (2001-12-17 20:10:42) 得0分 
int i=11;
CString str="test";
CString addition;
addition.Format("%d",i);
str+=addition;
就可以了。 

11。關於sprintf類型轉換的問題
sprintf(buf,"select price from ls01 where p_date>='%'",t_date)
其中t_date是CTime類型,%後面應該是什麼呢?%s是String類型,%c是char,那麼CTime型對應的是什麼呢? 
 
回覆人: yakai(日落長河) (2001-12-17 17:45:47) 得0分 
sprintf(buf,"select price from ls01 where p_date>='%S'",(LPCSTR)t_date.Format( "%A, %B %d, %Y" ));
如果不行,就
char temp[50];
CString str=t_date.Format( "%A, %B %d, %Y" );
strcpy(temp,(LPCSTR)str);
sprintf(buf,"select price from ls01 where p_date>='%S'",temp);
CTime::Format返回CString 
回覆人: loh(樂嘯天涯) (2001-12-17 17:52:57) 得0分 
wait

don't know 
回覆人: masterz() (2001-12-17 20:21:05) 得0分 
SQL語句中日期要寫成字符串"yyyymmdd" 


12。類型轉換 unsigned int <==>CString??
回覆次數:8
發表時間:2001-12-17 10:25:23

unsigned int f;//unsigned int 0~4294967295
CString g;
f=2300000000;
g.Format("%d",f);
AfxMessageBox(g);
出錯。 


回覆人: ydogg(灰毛兔頻頻) (2001-12-17 10:31:29) 得0分 
unsigned int f;//unsigned int 0~4294967295
CString g;
f=2300000000;
g.Format("%d",f);
MessageBox(g);//使用AfxMessageBox,需要窗口的句炳參數

回覆人: asdmusic8(asdmusic8) (2001-12-17 10:35:15) 得0分 
我 AfxMessageBox(g); 和MessageBox(g); 都不錯。
錯的是g.從 2300000000=》1994967296

回覆人: asdmusic8(asdmusic8) (2001-12-17 10:36:10) 得0分 
是2300000000=》-1994967296 類型轉換錯。

回覆人: ydogg(灰毛兔頻頻) (2001-12-17 10:37:54) 得6分 
g.Format("%u",f);

回覆人: asdmusic8(asdmusic8) (2001-12-17 10:40:24) 得0分 
to dgsnmpoperate 那怎麼從 CString ==>>unsigned int 
回覆人: kingfish(今飛) (2001-12-17 10:42:10) 得6分 
既然是 unsigned int,
超過 0x7f000000 (2130706432) 當然不能用 %d (signed int)用%u 
回覆人: kingfish(今飛) (2001-12-17 10:44:57) 得8分 
CString ==>>unsigned int  
char *p = (LPSTR)(LPCSTR) g;
f = atoi(p); 

13。static_cast、dynamic_cast 和直接類型轉換(如 (void *)p )的區別?
發表時間:2001-12-14 9:31:13

先拷貝MSDN中的一小段話:
class B { ... };
class C : public B { ... };
class D : public C { ... };

void f(D* pd)
{
C* pc = dynamic_cast<C*>(pd); // ok: C is a direct base class
// pc points to C subobject of pd 

B* pb = dynamic_cast<B*>(pd); // ok: B is an indirect base class
// pb points to B subobject of pd 
...
}
我已經知道 static_cast 和 dynamic_cast 的作用,但MSDN中並沒有提到這兩個操作符與直接類型轉換如
void f(D* pd)
{
C* pc = (C*)(pd);

B* pb = (B*)(pd); 
...
}
的不同啊。不知道那位知道的告訴一聲,在此不勝感謝,50分奉上。

回覆貼子:ysdesigned(清泉) (2001-12-14 10:03:07) 得0分 
static_cast、dynamic_cast 代 替 簡 單 的 強 制 轉 化, 從 而 消 除 多 繼 承 帶 來 的 歧 義。 使 用 這 兩 個 運 算 符 號, 我 們可以 在 對 象 運 行 過 程 中 獲 取 對 象 的 類 型 信 息
dynamic_cast 用於多態類型的轉換
static_cast 用於非多態類型的轉換

回覆人: masterz() (2001-12-14 10:05:48) 得0分 
static_cast<...>compile時能發現不正確的指針類型轉換
dynamic_cast<...>運行時如果發現是不正確的指針類型轉換會返回NULL
(void*)強制轉換,如果是不正確的指針類型轉換,沒有辦法檢查,不如上面2中安全 
回覆人: meady() (2001-12-14 11:29:05) 得0分 
類型安全 
回覆人: bluecrest(爲什麼我的VC還是那麼的菜) (2001-12-14 11:45:34) 得0分 
com技術內幕介紹過
我剛看完就忘了 

14。byte數據類型轉換成int型??
我用byte型讀進一組數據想把他轉成int型進行運算如何做呢?
如果再把int型轉回byte又怎麼實現呢? 

回覆人: louifox(蘭陵笑笑生) (2001-12-6 9:18:38) 得0分 
用下面這些宏:
WORD MAKEWORD(
BYTE bLow, 
BYTE bHigh 
);
BYTE LOBYTE(
WORD wValue 
);
BYTE HIBYTE(
WORD wValue 
);

回覆人: chskim(大刀闊斧) (2001-12-6 9:21:04) 得0分 
int i;
BYTE b;
b=128;
i=(int)b;

回覆人: nannet(似的) (2001-12-6 9:38:24) 得0分 
這個宏怎麼用呀?有沒有簡單一點兒的,我現在能把BYTE 轉成INT 型了,再轉回去直接賦值可以嗎? 
回覆人: louifox(蘭陵笑笑生) (2001-12-6 9:46:24) 得20分 
WORD wa;
BYTE ba=32,bb=64;
wa=MAKEWORD(ba,bb);
...
WORD wa=1234;
BYTE ba,bb;
ba=LOBYTE(wa);
bb=LOBYTE(wa);

回覆人: nannet(似的) (2001-12-6 9:54:55) 得0分 
問題解決了,多謝各位 

15。類型轉換的問題,unsigned int --> lptstr/lpctstr??
發表時間:2001-8-7 23:49:41
如果強制轉換的話,會出現致命錯誤,有什麼好的辦法呢?
能列舉一些其他的辦法嗎?
謝謝大蝦! 

回覆人: AlphaOne(總是第一個倒下) (2001-8-8 0:02:43) 得5分 
你爲什麼要強行轉換呢?
如果你是要把int 的值作爲 lptstr/lpctstr 的內容的話,
可以用CString:
unsigned int a = 100;
LPCTSTR lpText;
CString str;
str.Format("%d",a);
lpText = (LPCTSTR)str;

回覆人: tryibest(編の魂) (2001-8-8 8:20:20) 得5分 
wsprintf(str,"%u",ui); 
回覆人: zzh() (2001-8-8 9:04:39) 得5分 
這種情況不需要進行強制轉換,直接使用wsprintf就可以了。 
回覆人: GJA106(中文字符) (2001-8-8 10:10:51) 得5分 
unsigned int m_na=22;
LPTSTR lptstr;
wsprintf(lptstr,"%u",m_na);

16。關於COM類型轉換問題??
我定義了兩個變量,一個是void *piaRef=new unsigned char[1000];另一個是m_Temp=new CComVariant();我的問題是如何將piaRef中的值
COPY到m_Temp中。 

回覆人: nichang() (2001-11-21 15:34:04) 得0分 
CComBSTR bsRef=piaRef;
m_Temp=bsRef.copy() 
回覆人: VincentChin(瘟神) (2001-11-21 17:04:24) 得0分 
CComBSTR bsRef=piaRef;
//error C2440: 'initializing' : cannot convert from 'void *' to 'class ATL::CComBSTR'
m_Temp=bsRef.copy();
//error C2440: '=' : cannot convert from 'unsigned short *' to 'class ATL::CComVariant *' 
回覆人: nichang() (2001-11-21 17:14:28) 得0分 
將void*改爲unsigned char * 
回覆人: VincentChin(瘟神) (2001-11-21 17:22:22) 得0分 
我用CComBSTR bsRef=(unsigned char*)piaRef,也不行嗎? 
回覆人: VincentChin(瘟神) (2001-11-21 17:28:06) 得0分 
會報錯:
error C2440: 'type cast' : cannot convert from 'unsigned char *' to 'class ATL::CComBSTR' 
回覆人: nichang() (2001-11-22 9:12:14) 得0分 
m_Temp=::SysAllocString((OLECHAR *)piaRef) 
回覆人: VincentChin(瘟神) (2001-11-22 10:43:07) 得0分 
//error C2440: '=' : cannot convert from 'unsigned short *' to 'class ATL::CComVariant *' 
回覆人: VincentChin(瘟神) (2001-11-22 11:22:35) 得0分 
m_Temp=new CComVariant(::SysAllocString(OLECHAR *)piaRef));沒有出錯,但是我的m_Temp是COM組件中的一個PROPERTY,我想返回的是
unsigned char類型(單字節),但經過上述轉換後,就不再是單字節了呀!怎麼辦? 
回覆人: jiangsheng(蔣晟) (2001-11-22 11:36:58) 得0分 
把這個屬性的類型改成BSTR 
回覆人: GrayWhite(灰白) (2001-11-22 12:01:09) 得0分 
m_Temp = new CComVariant((char*) piaRef);就可以了。VB就是用的BSTR,你要給誰用阿?VC不用VARIANT的。 
回覆人: GrayWhite(灰白) (2001-11-22 12:18:18) 得19分 
哦,我明白了,你要各字節數組:
SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, 1000);
if (!psa)
_com_issue_error(ERROR_NOT_ENOUGH_MEMORY);

HRESULT hr
for (long i = 0; i < 2; i ++)
{
if (FAILED (hr = SafeArrayPutElement(psa, &i, piaRef + i)))
_com_issue_error(hr);
}

_variant_t va; // include <comdef.h>
va.vt = VT_ARRAY | VT_UI1;
va.parray = psa;

m_Temp = new CComVariant(va); 
回覆人: VincentChin(瘟神) (2001-11-22 14:21:08) 得0分 
SafeArrayPutElement(psa, &i, piaRef + i)
//error C2036: 'void *' : unknown size 
回覆人: VincentChin(瘟神) (2001-11-22 14:46:05) 得0分 
To GrayWhite:爲什麼要for(long i=0;i<2;i++)? 
回覆人: nichang() (2001-11-22 15:16:35) 得0分 
到底你想怎樣轉換嘛,是將數組內的值拷貝到CComVariant中存爲字符串嗎? 
回覆人: VincentChin(瘟神) (2001-11-22 15:28:35) 得0分 
我是想把piaRef中的值照原樣返回給其它程序使用。我正在做的是一個COM組件。謝謝各位! 
回覆人: nichang() (2001-11-22 15:34:40) 得10分 
unsigned char *s=new unsigned char[1000];
strcpy((char*)s,"1234");//可以用你自己方法設置s中的值。
BSTR bstrS;
oleS=A2WBSTR((char*)s);//將char*轉換成BSTR類型

CComVariant comVT;
comVT=oleS;//將BSTR轉成CComVariant,這裏一步也可,comVT=A2WBSTR((char*)s);

回覆人: VincentChin(瘟神) (2001-11-22 16:54:07) 得0分 
謝謝你!
但我還有一個問題,就是如果在s中有'/0'之類的東西我該怎麼返回呢?char *遇到'/0'會認爲到頭了。完整的設計是這樣的,我定義一個void * 用來從一個外部設備獲取數據,該數據應該是unsigned char,我想把這個返回的數據作爲屬性傳出,讓其它應用使用(如VB)。 
回覆人: nichang() (2001-11-22 17:18:09) 得0分 
將'/0'轉換成其它如'/1'就OK了, 
回覆人: jiangsheng(蔣晟) (2001-11-22 18:07:16) 得0分 
用字符串數組 
回覆人: VincentChin(瘟神) (2001-11-23 15:54:39) 得0分 
謝謝各位的回覆!我的問題解決了!如下:
SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, 1000);
if (!psa)
return S_FALSE;
HRESULT hr;
for (long i = 0; i < 1000; i ++)
if (FAILED (hr = SafeArrayPutElement(psa, &i, ((unsigned char*)piaRefTemplate) + i)))
return S_FALSE;
VARIANT va;
va.vt = VT_ARRAY | VT_UI1;
va.parray = psa;
CComVariant *m_Temp = new CComVariant();
m_Temp->Copy(&va);

17。類型轉換 static_cast reinterprete_cast 的區別??
static_cast reinterprete_cast 的區別 

回覆人: tar(GPS) (2001-11-21 10:06:41) 得0分 
static_cast會檢查轉換類型健的相關性
如果沒有的畫會有編譯錯誤
reinterprete_cast就是硬轉了 
回覆人: tigerwoods(tao) (2001-11-21 12:28:19) 得0分 
是否可以這樣理解:在多重繼承中,static_cast可實現對象指針的移動,從而指向正確的父類對象部分,而reinterprete_cast不作偏移? 
回覆人: liu_feng_fly(我恨死驅動程序了,哎,就是爲了混口飯吃) (2001-11-21 12:35:14) 得0分 
在多重繼承中可以用dynamic_cast啊 

18。那如何取得CString中的字符串??
回覆人: nichang() (2001-11-5 17:06:00) 得0分 
=(LPCTSTR)CString變量 
回覆人: snake1122(領悟) (2001-11-5 17:12:16) 得0分 
方法太多了:
GetAt,Left,Mid,Right等等,就看你怎麼取了! 
回覆人: dusb(保時捷) (2001-11-5 17:34:29) 得0分 
可是不管是GetAt,Left,Mid,Right返回類型都是CString,還是不能用,我是要取其中的字符串,奇怪的是,VC中沒有string類型。(我要的字符串是給樹型控件中的分支名稱) 
回覆人: Alps_lou(雲飛揚) (2001-11-5 17:41:36) 得0分 
有string類型的啊,要包含<string> 
回覆人: luxes() (2001-11-5 17:42:19) 得0分 
加上(LPCTSTR),相當於一個const char *了,還不能用? 
回覆人: wt007(tt) (2001-11-5 17:48:33) 得0分 
GetBuffer 
回覆人: espon99() (2001-11-5 17:54:06) 得20分 
(LPSTR)(LPCTSTR)

回覆人: ineedyou(古寺僧) (2001-11-5 17:59:29) 得0分 
...m_str.GetBuffer(needlen)...;
....
m_str.ReleaseBuffer() 
回覆人: dusb(保時捷) (2001-11-6 15:08:36) 得0分 
espon99大俠,果然是絕招,不過能否解釋一下啊? 

19。如何從CString類型轉換爲Unicode string 類型?
回覆人: ychener(貧血) (2001-10-20 10:28:48) 得0分 
CString本身就支持Unicode的。 
只要你選擇的是UniCode編譯,生成的可執行程序就是支持UniCode的 

回覆人: ychener(貧血) (2001-10-20 10:30:04) 得0分 
CString類是自適應的就像TCHAR一樣,如果你定義了UniCode宏 就會以UniCode編譯 

回覆人: xjl1980_81(阿龍) (2001-10-20 10:35:16) 得0分 
不是呀,我有個函數中有一個參數需Unicode string 類型的,比如應該填L"abc",而且引號中的內容要有變化,現在我有一個 temp變量,是CString類型的,如何用呀? 
回覆人: xt_jat(桑巴) (2001-10-20 10:39:37) 得0分 
_T()
_TEXT()
行不行? 
回覆人: xjl1980_81(阿龍) (2001-10-20 10:43:18) 得0分 
不行 
回覆人: Jeffery__Chen() (2001-10-20 11:04:53) 得0分 
強制轉化:
CString temp;
WCHAR wTemp = (WCHAR)temp; 
回覆人: xjl1980_81(阿龍) (2001-10-20 11:37:06) 得0分 
to:Jeffery__Chen() 
不對呀,出現不能轉換的錯誤 
回覆人: hongzhh(關兒) (2001-10-20 11:39:42) 得0分 
問題是這樣的:
temp 是 CString類型變量,值爲zhh
現在有一個API 
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(
HCERTSTORE hCertStore, 
DWORD dwCertEncodingType, 
DWORD dwFindFlags, 
DWORD dwFindType, 
const void *pvFindPara, //此處用 L"zhh" 沒問題 
//請問怎麼轉換 可以 用temp

PCCERT_CONTEXT pPrevCertContext 
);

在此謝謝大家,請幫忙看看

回覆人: hongzhh(關兒) (2001-10-20 13:27:10) 得0分 
WCHAR wszDomain[256]; 
MultiByteToWideChar( CP_ACP, 0, temp,
strlen(temp)+1, wszUserName, 
sizeof(wszUserName)/sizeof(wszUserName[0]) );


wszUserName就是轉換後的值

回覆人: ychener(貧血) (2001-10-23 11:43:05) 得0分 
只要你用的是CString的函數就行的,如果你要用類似strcpy函數時,看看MSDN中一般情況下都有響應的函數對於Unicode的。只要換成_tcscpy等等。 
回覆人: ychener(貧血) (2001-10-23 11:44:10) 得0分 
你有沒有定義Unicode宏?  
20。請問在用ATL且不支持MFC的組件開發中,如何將從數據庫中讀到的DATE數據類型轉換回爲字符串?? 

復人: zhxuys(zhxuys) (2001-9-24 10:36:47) 得0分 
ATL把datetime類型的列映射爲DBTIMESTAMP類型,可取出該類型的year、month、day等,然後將這些數據傳遞迴客戶端,在客戶端用CTime來構造 
回覆人: YUANXU(旭) (2001-9-24 11:18:14) 得0分 
to zhxuys:CTime是MFC類,在ATL 不支持MFC時不能用。DATE其實質是個double* 
回覆人: zhxuys(zhxuys) (2001-9-24 11:57:01) 得0分 
你在客戶端與服務器端只用ATL規定的數據類型或VARIANT類型,而在客戶端,可以用MFC來重新構造想要的數據結構 

21。類型轉換,CString to wchar_t ??

CString ss("aabb");
wchar_t* cc;
cc=ss.AllocSysString();

22。如何將CString類型轉換爲_bstr_t類型?
回覆人: wei97081116(韋小寶) (2001-9-4 11:19:30) 得20分 
CString b;
_bstr_t a;
a=(_bstr_t)b; 

回覆人: zhaozhen1212(趙振) (2001-9-18 1:30:18) 得0分 
_bstr_t a=b.AllocSysString();;

23。如何把一個CString類型轉換成一個普通的字符串,如char*?

回覆人: liu_feng_fly(我恨死驅動程序了,哎,就是爲了混口飯吃) (2001-9-17 18:00:52) 得0分 
所以,直接用就可以,因爲類裏邊有這樣的轉換函數 
回覆人: ydogg(灰毛兔頻頻) (2001-9-17 18:01:21) 得0分 
CString show;

char *p = show.GetBuffer(show.GetLength()); 
回覆人: jiangping_zhu(娜可露露之風之刃) (2001-9-17 18:02:05) 得0分 
(char*)(LPCTSTR)str 
回覆人: bmouse(老鼠) (2001-9-18 0:10:56) 得0分 
同意樓上! 
回覆人: bmouse(老鼠) (2001-9-18 0:13:22) 得0分 
你還可以通過GetBuff來直接操作CString的緩衝區,不過要記着釋放緩衝區. 

24。CString 類型轉換成 unsigned char類型嗎??
回覆人: LJN(*)風流倜儻無人及,玉樹偏又臨風立(*) (2001-9-17 12:46:01) 得0分 
可以用CString.GetBuffer函數 
回覆人: xpmao() (2001-9-17 13:09:09) 得0分 
CString strWork;
MessageBox(0,(LPSTR)strWork,0,0);
或MessageBox(0,strWork.GetBuffer(0),0,0);

回覆人: sandd(降龍掌) (2001-9-17 13:17:32) 得0分 
CString string;

(LPCTSTR)string; 
回覆人: jeff_hunter(PandaLee) (2001-9-17 13:45:30) 得0分 
(unsigned char *)(LPCTSTR) 
回覆人: fandh(好了) (2001-9-17 14:00:57) 得0分 
用(unsigned char *)(LPCTSTR)即可  
回覆人: ygd(ygd) (2001-9-17 16:11:17) 得0分 
unsigned char *p;
CString str;
int length=str.GetLength();
for(int i=0;i<length;i++)
p[i]=str.GetAt(i); 
回覆人: swordbroken(斷劍書生) (2001-9-17 16:25:57) 得0分 
CString str;
unsigned char string[30];
strcpy(string,str); 

25。何將一個unsigned int 類型變量值賦給類型爲unsigned short的變量,並保證數值不丟失(當然數值在一定範圍內)?
回覆人: maxsuy(魔法師兔子) (2001-8-14 16:37:30) 得0分 
直接=就OK了 
回覆人: oppmm(ppmm) (2001-8-14 16:38:11) 得0分 
直接賦值 
回覆人: milefo(彌勒佛) (2001-8-14 16:40:40) 得0分 
如果數值在一定範圍內怎麼回丟失呢?
unsigned short a;
unsigned int b;
a=( b & 0xffff);
你試試看吧!

26。CString ----char* 
定義了char* aa的變量,現在有一個CString的變量bb,怎樣把bb的值賦給aa呢? 

回覆人: emmai(WaTaXiWaWaTaXi) (2001-8-10 11:57:33) 得0分 
aa=bb.GetBuffer(); 
回覆人: hswqs(??????????????????) (2001-8-10 11:59:01) 得0分 
aa= (LPSTR)(LPCTSTR)bb; 
回覆人: ydogg(灰毛兔) (2001-8-10 12:27:23) 得0分 
1.aa=bb.GetBuffer(bb.GetLenth());//第一種方法
2.aa= (LPSTR)(LPCTSTR)bb; //第二種方法 
回覆人: zhizhi() (2001-8-10 13:16:23) 得0分 
aa= (char *)(LPCTSTR)bb,hehe 

27。在一個COM的接口函數中有一個 BSTR* 類型的參數,需要把一個 char * 類型轉換爲 BSTR* 類型,不知道如何轉換? 由於調用這個函數後需要把這個參數值再取出來所以只能用指針,另外在調用的時候應該用什麼類型的數據傳遞參數呢?大蝦幫忙。

BSTR bstr = SysAllocString(L"字符串");
這樣轉換,用的時候你用地址操作符&啊,要不指針還得new 

回覆人: yongyue2000i(小呂) (2001-9-9 18:38:26) 得13分 
CString str = "abcd";
BSTR bstr = str.AllocSysString(); 
回覆人: houjzs() (2001-9-9 19:14:44) 得13分 
BSTR b = SysAllocString(OLESTR("your string"));

28。要把一個double的數字輸出到CEdit控件是否需要類型轉換?
回覆人: jiangsheng(蔣晟) (2001-8-24 14:46:17) 得0分 
void AFXAPI DDX_Text( CDataExchange* pDX, int nIDC, double& value ); 
回覆人: xiezhsh(雪中行) (2001-8-24 14:56:22) 得0分 
假如你的CEdit相關的成員變量是Double型的,那根本用不着.(ClassWizard增加成員變量的對話框中,Variable Type選擇Double可) 
回覆人: xiezhsh(雪中行) (2001-8-24 14:58:16) 得0分 
假如你的CEdit相關的成員變量不是Double型的,是CString型,那就需要用ltoa()來轉換成CString型, 
回覆人: haven(大天) (2001-8-24 14:58:32) 得0分 
m_Edit.Fromat("%l",VarBouble);
updatedata(false); 
回覆人: 12345678() (2001-8-24 14:59:54) 得0分 
CString m_Edit.Format("%lf", doubleVar); 
GetDlgItem(EditID)->SetWindowText(m_strEdit); 

29。該如何把 WINDOWPLACEMENT * 轉換成 char **類型??

(char**)&pWP 

30。怎樣把CString的類型轉換成char*型的?
回覆人: dcz(dcz) (2001-8-19 19:13:27) 得5分 
// str is CString var
char* temp = strdup(str);
...
free(temp); 
回覆人: yu900(疾風之狼) (2001-8-19 19:57:25) 得0分 
getbuffer();即可! 
回覆人: aileen_long(挑戰2001) (2001-8-19 21:10:35) 得0分 
同意樓上的意見! 
回覆人: czh912() (2001-8-19 21:27:08) 得0分 
char buf[20];
printf(buf,"%s",string);

回覆人: casl(casl) (2001-8-19 22:59:44) 得5分 
CString s("abc");
char* temp=s.GetBuffer(10);
...
s.ReleaseBuffer(); 
回覆人: cocia(高亞) (2001-8-19 23:04:23) 得0分 
char* temp=s.GetBuffer(10);
10是什麼意思啊

回覆人: kevin_dong(夢仙人) (2001-8-20 10:26:35) 得0分 
// str is CString var
char* temp = strdup(str);
// free
free(temp); 
我的這段代碼在一個程序中能通過編譯,但是在另外一箇中總是出現cannot convert parameter 1 from 'class CString' to 'const char *'的錯誤。str和temp的類型都一樣。這是爲什麼?

回覆人: dcz(dcz) (2001-8-20 14:13:45) 得0分 
you may setting your compiler option to UNICODE, in this case, declare the var:

// str is CString var
_TCHAR* temp = _tcsdup(str);

// free
free(str);

31。SA,SB爲兩個結構類型??
SA* A;
SB* B;
(SB*)A->...(調用函數)
請問此時A的類型,是指向SA還是SB
此時編譯器是生成一個臨時指針嗎?
另外,
B=(SB*)A;此時A又是什麼類型???

回覆貼子: 
回覆人: ddeng(登登) (2001-8-9 17:13:58) 得0分 
A的類型始終是SA *
B的類型始終是SB *
當進行強制類型轉換時使的是臨時指針 
回覆人: gold_water(風雨無阻) (2001-8-9 17:30:46) 得0分 
同意樓上的。 

32。char buff[100],char UserName[50][100],怎麼將buff的值傳給UserName,是其成爲UserName數組中的某一項呢??

//0=<i<50
strcpy(UserName[i],buff); 
回覆人: Ashura(阿修羅) (2001-7-26 10:08:20) 得0分 
呵呵,benbensan搶先一步。 
回覆人: tuita(鬥牛士) (2001-7-26 10:13:22) 得0分 
for (i=0;i<100;i++)
*(*(username+x)+i)=*(buffer+i)
其中0《X〈50
benbensan寫的也對

回覆人: kekeke(我是來向大家學習的) (2001-7-26 10:24:22) 得0分 
那反過來呢?把UserName中的某一項讀出賦值給buff呢?怎麼弄? 
回覆人: benbensan(笨笨三) (2001-7-26 10:26:53) 得0分 
//0=<i<50
strcpy(UserName[i],buff); 
回覆人: benbensan(笨笨三) (2001-7-26 10:28:15) 得0分 
對不起,能錯了,不過建議你看一下C語言了的指針和數組
//0=<i<50
strcpy(buff,UserName[i]); 

回覆人: jfzsl(剿匪總司令) (2001-7-26 10:32:57) 得0分 
好好看看老潭的書先!OK? 
回覆人: kekeke(我是來向大家學習的) (2001-7-26 10:44:25) 得0分 
好。。。。! 

33。請問怎樣把SYSTEMTIME類型轉換成time_t類型?
SYSTEMTIME st;
GetLocalTime(&st);
CTime tm(st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
time_t t = tm.GetTime();

34。unsigned char Exponent[10]; //e
unsigned long eBytes; //e的字節數
如何轉換成DWord型! ??


用強制類型轉換呀
(DWord)eBeytes;
(DWord)Exponent[i];//(0<=i<=10);

回覆人: xjl1980_81(阿龍) (2001-7-26 16:47:29) 得0分 
我是說把e轉換成DWORD型
也就是說把Exponent中的內容轉換成DWORD型

回覆人: cloudshadow1(雲影) (2001-7-26 17:13:30) 得0分 
用強制類型轉換就可以了,(DWORD的高24位自動加0)
DWORD Des[10]
for (int i=0;i<11;i++)
Des[i]=Exponent[i];
至於那個ULONG的也是用強制類型軟換就可以了

35。請問怎樣把time_t類型轉換成SYSTEMTIME類型?
回覆人: haven(大天) (2001-7-26 17:12:36) 得0分 
typedef struct _SYSTEMTIME
typedef long time_t
很明顯不行嘛! 
回覆人: facexy(FACE仔) (2001-7-26 17:17:38) 得0分 
哎呀,問錯了,前後對象相反了;-(
忙昏了的結果…………

另外,TO 樓上的:
轉換是可以的
struct tm *tblock;
SYSTEMTIME SystemTime;
memset(&SystemTime,0,sizeof(SYSTEMTIME));
tblock=localtime(&timer);
SystemTime.wYear=tblock->tm_year+1900;
SystemTime.wMonth=tblock->tm_mon+1;
SystemTime.wDay=tblock->tm_mday;
SystemTime.wHour=tblock->tm_hour;
SystemTime.wMinute=tblock->tm_min;
SystemTime.wSecond=tblock->tm_sec;
SystemTime.wDayOfWeek=tblock->tm_wday;
return &SystemTime; 
回覆人: zjh73(大章魚) (2001-7-26 20:28:28) 得0分 
有兩種方法:
1、用CTime類
先用time_t類型構造一個CTime對象,再定義一個SYSTEMTIME結構,最後用CTime類的成員函數GetAsSystemTime將時間轉換到SYSTEMTIME結構中
即可。
2、用gmtime函數
gmtime函數將time_t時間轉換到tm結構中並返回一個tm指針,再將tm結構的相對應的項賦給SYSTEMTIME相對應的項即可,不過用這種方法要注
意這兩種結構在天、星期等方面的記數方法有點區別,一個一般從0開始,一個一般從1開始,賦值時要注意校正,還有要注意的是SYSTEMTIME
結構中有一項是毫秒,而time_t是以秒記數的。 
回覆人: zjh73(大章魚) (2001-7-26 20:32:13) 得0分 
反過來也可以用Ctime類的方法
就是先用SYSTEMTIME結構構造一個CTime對象,在用CTime類中的成員函數GetTime返回一個對應的time_t即可。 36。我現在正在學習SDK編程,遇到的問題是:
我定義了一個靜態長整形變量,
static long lScore=0;
我想把窗口的標題換成長整形數值,用SetWindowText函數來實現,
由於它的第二個參數要求數據類型爲 unsigned short *,但用其來實現強制轉換時
總是出現編譯錯誤:
cannot convert parameter 2 from 'unsigned short *' to 'const char *'
後來改成來LPCTSTR 來實現強制轉換,沒有出現編譯錯誤,但函數總是執行不成功,
請教各位高人,這倒底是怎麼回事???

回覆貼子: 
回覆人: prog_st(st) (2001-8-4 21:20:07) 得0分 
/* ITOA.C: This program converts integers of various
* sizes to strings in various radixes.
*/

#include <stdlib.h>
#include <stdio.h>

void main( void )
{
char buffer[20];
int i = 3445;
long l = -344115L;
unsigned long ul = 1234567890UL;

_itoa( i, buffer, 10 );
printf( "String of integer %d (radix 10): %s/n", i, buffer );
_itoa( i, buffer, 16 );
printf( "String of integer %d (radix 16): 0x%s/n", i, buffer );
_itoa( i, buffer, 2 );
printf( "String of integer %d (radix 2): %s/n", i, buffer );

_ltoa( l, buffer, 16 );
printf( "String of long int %ld (radix 16): 0x%s/n", l, 
buffer );

_ultoa( ul, buffer, 16 );
printf( "String of unsigned long %lu (radix 16): 0x%s/n", ul,
buffer );
}


Output

String of integer 3445 (radix 10): 3445
String of integer 3445 (radix 16): 0xd75
String of integer 3445 (radix 2): 110101110101
String of long int -344115 (radix 16): 0xfffabfcd
String of unsigned long 1234567890 (radix 16): 0x499602d2


回覆人: lwg7603(刑滿釋放人員) (2001-8-4 21:36:15) 得0分 
TCHAR str[255]={_T('/0')};
_stprintf(str,_T("%d"),lScore);
SetWindowText(hwnd,str);

37。我用socket發送的的buf中間需要的是 char *類型的數據,我想將一個 struct 直接轉換成 char * 發過去。
我用
struct ABCD *abcd;
char *buf;
abcd = (ABCD *)calloc(1,sizeof(ABCD));
buf = (char *)calloc(1,sizeof(ABCD));
///
給abcd 中間賦值,其中有多個char[]的值和int 的值
///
memcpy(buf,abcd,sizeof(ABCD));
//strcpy(buf,(char *)abcd);也不可以
sock(host,buf,....);
//sock(host,(char *)buf,...);也不可以
問題就是在這裏,這個buf中間的值總是不對,大家知道爲什麼否。

回覆人: wolf721() (2001-7-30 18:18:34) 得5分 
你傳的是個指針值,而不是數據 
回覆人: kiko_lee(到處瞧瞧) (2001-7-30 18:50:49) 得0分 
但是用memcpy這個是將整個數據都複製過去 
回覆人: lz_0618(lz_0618) (2001-7-30 19:26:44) 得5分 
你用的VC???改成ABCD *abcd;後編譯一點問題也沒有啊!
sock(host,buf,....);這不知是什麼,自定義函數?

typedef struct _ABCD
{
int ID;
char Name[10];
}ABCD;

.......


ABCD *abcd;
char *buf;
abcd = (ABCD *)calloc(2,sizeof(ABCD));
buf = (char *)calloc(2,sizeof(ABCD));
///
//給abcd 中間賦值,其中有多個char[]的值和int 的值
abcd[0].ID =1;
abcd[1].ID =2;
///
memcpy(buf,abcd,2*sizeof(ABCD));
strcpy(buf,(char *)abcd);//也不可以

buf中的內容也正確!!

回覆人: kiko_lee(到處瞧瞧) (2001-7-31 8:57:52) 得0分 
我按照樓上的兄弟說的,做了一下,但是仍然做不下來,我用
memcpy(buf,abcd,sizeof(ABCD));
中間的abcd,不知道是不是地址的問題。 
回覆人: supersusheng(小蘇) (2001-7-31 14:30:42) 得0分 
老大,你sizeof()得出的數值事多大,看看吧。 
回覆人: ydogg(灰毛兔) (2001-7-31 14:41:52) 得0分 
只能傳遞流數據,結構是傳遞不過去的。 
回覆人: IamNotMan(NorGirl) (2001-7-31 14:50:53) 得5分 
我常這麼用
ABCD a ;
//給a的各個域賦值(一定不能含有指針項)
char* buff = new char[sizeof(ABCD)];
memcpy(buff,&a,sizeof(ABCD));
//或者 *(ABCD*)buff = a;
.................
如果buff裏的數對,說明問題不在這兒吧

回覆人: zb_china(最後一座水車zb_china新浪) (2001-7-31 15:16:24) 得0分 
看不明白 
回覆人: eggplant(拉拉) (2001-7-31 15:42:48) 得0分 
最好使用memcpy(),因爲struct中的值有可能包含零字節,所以strcpy()可能不對,如果傳遞struct,最好把struct的字節對齊改爲以字節爲單位。 
回覆人: lvfengxun(lfx) (2001-7-31 16:06:57) 得5分 
直接將結構指針作爲send的參數發就可以了,還用轉換什麼
有必要在這裏討論嗎?
struct AA
{
int a;
char b[100];
};
struct AA aa;
aa.a=11;
strcpy(aa.b,"aaa");
send(hSocket,(char *)(&aa),sizeof(aa),0);
//OK 
回覆人: mydewang(mydewang) (2001-7-31 16:33:21) 得0分 
其實這裏是一個字節對齊的問題,
比如
struct AA
{
int a;
char b;
};
那麼sizeof( struct AA )就不等於5了,而是8了,所以,將這個結構賦值給一個char *,裏面會多出一些零...

需要解決這個問題,可以在Project->Setting->Link->Project Options里加上/Zp1

另外,可以參考一下MSDN裏/Zp的編譯選項..... 
回覆人: lz_0618(lz_0618) (2001-7-31 19:43:54) 得0分 
根本不是什麼字節對齊的問題,我上面的程序經過測試都好用啊,這位老兄用我的那段程序究竟是什麼錯誤,能說清楚點嗎???

我這邊用socket發送結構是一點問題也沒有啊,而且是在VC和Delphi編的程序間通訊,當然,這時應該注意字節對齊的問題了,在VC程序間,
只要不是故意將服務器和客戶端的編譯環境設的不一樣,肯定是沒有什麼問題的,最多是多傳幾個Bit罷了。 
回覆人: kiko_lee(到處瞧瞧) (2001-8-3 11:02:51) 得0分 
我發現將char * memcpy 到 char * 中間都有點問題,但是如果放到 char []中間就可以了,大家知道爲什麼否? 
回覆人: ydogg(灰毛兔) (2001-8-3 11:40:35) 得0分 
memcpy不copy最後的'/0'... 
回覆人: wenjunlin2000(微軟剋星) (2001-8-3 14:32:17) 得0分 
是你看錯了
因爲char*是以0 結尾的

回覆人: mc_music(狂沙) (2001-8-3 15:07:21) 得0分 
請注意我的程序:
struct ABCD *abcd;
char *buf;
abcd = (ABCD *)calloc(1,sizeof(ABCD));
//初始化abcd
buf=abcd;//指針直接符值就可以了 
回覆人: zhangnanonnet(WinSockZhang) (2001-8-3 16:21:03) 得0分 
你試試把類型變爲BYTE 
回覆人: kiko_lee(到處瞧瞧) (2001-8-7 9:21:08) 得0分 
不管了,給分,大家都有不少的建議呢。 


38。double dou=12.34;我如何可以得到char * ch="12.34";轉換函數是什麼?

回覆人: wyzegg(蛋) (2001-7-24 21:26:04) 得50分 
double dou=12.34;
char * ch;
ch=malloc(100);
sprintf(ch,"%5.2f",dou); 
回覆人: wyzegg(蛋) (2001-7-24 21:28:24) 得0分 
或者
#include <stdlib.h>
#include <stdio.h>

void main( void )
{
int decimal, sign;
char *buffer;
int precision = 10;
double source = 3.1415926535;

buffer = _ecvt( source, precision, &decimal, &sign );
printf( "source: %2.10f buffer: '%s' decimal: %d sign: %d/n",
source, buffer, decimal, sign );
}

但是第一種常用 
回覆人: Matrix_w(學會一點點) (2001-7-24 21:32:43) 得30分 
int decimal, sign;
double dou =12.34;
char* ch;
ch = _ecvt(dou,4,&decimal,&sign);

回覆人: imhua(華弟) (2001-7-24 21:35:02) 得20分 
double dou=12.34;
char *str;
gcvt(dou,5,str); //5是長度
MessageBox(str); 
回覆人: Matrix_w(學會一點點) (2001-7-24 21:37:58) 得0分 
/* _GCVT.C: This program converts -3.1415e5
* to its string representation.
*/

#include <stdlib.h>
#include <stdio.h>

void main( void )
{
char buffer[50];
double source = -3.1415e5;
_gcvt( source, 7, buffer );
printf( "source: %f buffer: '%s'/n", source, buffer );
_gcvt( source, 7, buffer );
printf( "source: %e buffer: '%s'/n", source, buffer );
}


Output

source: -314150.000000 buffer: '-314150.'
source: -3.141500e+005 buffer: '-314150.'

39。 我在ADO中調用一個存儲過程,存儲過程有三個輸入參數@useradd char(30),@username char(10),@userage char(3),現在要把char 
*addr,char *name,char *age分別賦值給他們。??
我做了如下定義:
_ParameterPtr para1;
_variant_t var1,var2,var3;
==============================================================
var1.vt=VT_BSTR;
var1.bstrval=addr;/////(編譯錯誤)
==============================================================
para1=m_pCommand->CreateParameter(L"useradd",adBSTR,adParamInput,30,var1);
m_pCommand->Parameters->Append(para1);
編譯結果出現下面錯誤:
cannot convert from 'char *' to 'unsigned short *
不知道類型是不是選擇VT_BSTR?
回覆人:tar(GPS) (2001-7-12 18:49:05) 得15分 
var1.bstrval應該指向寬字符的字符串,
即unicode字符串
use _bstr_t to convert it

_bstr_t var1(addr);

 回覆人:happyhackwang() (2001-7-12 20:06:48) 得5分 
char *要進行轉換成BSTR

 回覆人:WhiteWaterBlueSky(瘋狂數碼) (2001-7-13 9:35:15) 得10分 
SDK中是這樣的
1。先用MultiByteToWideChar把char* 轉爲wchar_t*
2。再用SysAllocString把wchar_t*轉爲BSTR 

 回覆人:tar(GPS) (2001-7-13 14:10:01) 得0分 
faint,我都已經把語句寫出來了
_bstr_t a(addr);
var1.vt=VT_BSTR;
var1.bstrval=(wchar_t *)a; 

 回覆人:xwchena(西風之神) (2001-7-13 15:57:00) 得0分 
大哥,我改完之後記錄集無結果返回。我的代碼是這樣的:
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdStoredProc);
if(!m_pRecordset->adoEOF)
{
result1=m_pRecordset->GetCollect((long)0);
if(result1.vt!=NULL)
{
result1.ChangeType(VT_BSTR);
CString strResult1=result1.bstrVal;
strcpy(resval,strResult1);
}
調試的時候看到執行完m_pCommand->Execute()後m_pRecordset就到了記錄集的尾部
而如果把char*型都改成int型,結果就能返回記錄集。
這是爲什麼啊???

 回覆人:tar(GPS) (2001-7-13 19:19:51) 得0分 
try adVarChar 
 回覆人:xwchena(西風之神) (2001-7-13 22:54:21) 得0分 
還是不行,記錄集沒有返回結果 
 回覆人:seesi(不是我想騙你,是我不知道怎麼才能不騙!) (2001-7-14 0:24:36)

40。如何將 BSTR pVal 賦給:unsigned char *pw;如何將:unsigned char digest[16]賦給 BSTR *pOutVal?

USES_CONVERSION;
  *pOutVal=SysAllocString(A2W((LPTSTR)digest));

unsigned char *pw = (unsigned char *)_com_util::ConvertBSTRToString(pInVal);

發佈了12 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章