• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Visual C++.NET中的字符串轉換方法

    發表于:2007-05-25來源:作者:點擊數: 標簽:C++.NETvisual字符串中的轉換
    Visual C++.NET涉及到ATL/ATL Server、MFC和托管C++等多種編程方式,不僅功能強大而且應用廣泛。在編程中,我們常常會遇到ANSI、Unicode以及BSTR不同編碼類型的字符串轉換操作。本文先介紹基本字符串類型,然后說明相關的類,如CComBSTR、_bstr_t、CStringT

    Visual C++.NET涉及到ATL/ATL Server、MFC和托管C++等多種編程方式,不僅功能強大而且應用廣泛。在編程中,我們常常會遇到ANSI、Unicode以及BSTR不同編碼類型的字符串轉換操作。本文先介紹基本字符串類型,然后說明相關的類,如CComBSTR、_bstr_t、CStringT等,最后討論它們的轉換方法,其中還包括使用最新ATL7.0的轉換類和宏,如CA2CT、CA2TEX等。

    一、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類進行不同數據類型以及字符編碼之間的相互轉換。

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>