Win字符串小結

ANSI和Unicode:

前者是單字節字符編碼,用來表示英語以及一些西歐語言的所有字符;後者是雙字節字符編碼,可以表示現代計算機涉及的所有字符(包括中文、日文等)。

顯然,使用Unicode更有利於國際化和本地化。除此之外,Windows所有核心函數也都需要Unicode字符串。在調用這些函數時,如果傳入ANSI字符串,那麼這些函數會將其轉換成Unicode再執行;反之,如果函數返回ANSI字符串,那麼操作系統也是先將其從Unicode字符串轉換爲ANSI字符串再返回。這樣的話,會增加開銷,而且埋下一些目前已知的轉換函數中存在的bug。

 

使用Unicode:

ANSI字符是由char類型來表示的,而在win編程中,Unicode字符由wchar_t(wide chartype)來表示的。在使用wchar_t類型時,需要在字符/字符串前加上大寫字母L來告訴編譯器這是Unicode字符/字符串,如下:

wchar_tc = L'a';

wchar_tstr[10] = L"hello";

爲了更有Windows特色,微軟做了如下類型定義(WinNT.h):

typedefchar CHAR;

typedefshort SHORT;

typedeflong LONG;

……

typedefwchar_t WCHAR;

在前面加P、LP或者C分別表示指針類型和Const限定,如:

typedef__nullterminated WCHAR*NWPSTR, *LPWSTR,*PWSTR;

……

typedef__nullterminated CONSTWCHAR *LPCWSTR,*PCWSTR;

……

typedef__nullterminated CHAR*NPSTR, *LPSTR,*PSTR;

……

typedef__nullterminated CONSTCHAR *LPCSTR,*PCSTR;

此外,爲了更通用一點,微軟還做了如下定義:

#ifdef UNICODE                     //r_winnt

 

#ifndef_TCHAR_DEFINED

typedefWCHAR TCHAR, *PTCHAR;

……

#define__TEXT(quote)L##quote     // r_winnt

 

#else  /* UNICODE */               //r_winnt

 

#ifndef _TCHAR_DEFINED

typedef char TCHAR, *PTCHAR;

……

#define __TEXT(quote) quote        // r_winnt

 

#endif/* UNICODE */                //r_winnt

#defineTEXT(quote)__TEXT(quote)  // r_winnt

即,使用TCHAR(以及PTSTR),無論字符集是ANSI還是Unicode都可以通過編譯,與之相應的通用字符串函數也出現了,比如_tcslen(tchar.h):

#ifdef_UNICODE

#define_tcslen        wcslen

#else

#define_tcslen     strlen

#endif

除了_tcslen,還有一堆其他的字符串處理函數,並且與_tcslen(計算字符串長度)不同,其它很多函數需要考慮安全性,比如_tcscpy或者_tcscat:

#ifdef_UNICODE

#define_tcscat        wcscat

#define_tcscat_s      wcscat_s

#define_tcscpy        wcscpy

#define_tcscpy_s      wcscpy_s

#else

#define_tcscat     strcat

#define_tcscat_s   strcat_s

#define_tcscpy     strcpy

#define_tcscpy_s   strcpy_s

#endif

緊接着處理函數的都是一個安全版本,這些安全性函數都是添加一個_s後綴,它們檢驗參數的有效性以及緩衝區是否足以容納結果。

最後,WinNT.h中還定義了宏TEXT、__TEXT,tchar.h中定義了宏_T、__T、_TEXT,這些宏的功能都是將字符/字符串轉換爲相應的通用類型,比如:

LPTSTRstr1 = _T("hello,world");

LPTSTRstr2 = TEXT("hello");

 

 

ATL字符串

 

COM字符類型

OLECHAR:不同操作系統上,OLECHAR對應不同字符類型,比如win32上對應wchar_t。

BSTR:一種帶長度前綴、含許多特殊語義的OLECHAR字符數組。

 

ATL字符串轉換類

所有類名稱都採用“C<源格式縮寫>2<目標格式縮寫>”的形式,第一個C表示類。縮寫中A代表指向char的字符指針(LPSTR)、W代表指向wchar_t的字符指針(LPWSTR)、T代表指向TCHAR的字符指針(LPTSTR)、OLE代表指向OLECHAR的字符指針(LPOLESTR)、C表示const限定符。

以下是字符串轉換類:

CA2W      CA2WEX  CA2T         CA2TEX    CA2CT     CA2CTEX

COLE2T   COLE2TEX         COLE2CT COLE2CTEX      CT2A

CT2AEX   CT2CA      CT2CAEX CT2OLE    CT2OLEEX        CT2COLE

CT2COLEEX     CT2W       CT2WEX   CT2CW     CT2CWEX        CW2A

CW2AEX CW2T       CW2TEX   CW2CT     CW2CTEX

 

BSTR與CComBSTR

BSTR是指向複合數據類型的指針,該複合數據類型由長度前綴、數據字符串和結束符組成,並且要使用COM內存管理函數來管理BSTR,其專用語義繁多,用法繁瑣。

CComBSTR是BSTR的一個封裝類。

 

CComBSTR

CComBSTR類維護一個BSTR類型的public成員m_str。

使用小結如下:

    //CComBSTR使用小結

    //1.構造

    //CComBSTR() {m_str = NULL; }

    CComBSTRstr1;

    //CComBSTR(LPCOLESTRpSrc);

    CComBSTRstr2(LPCOLESTR("hello,world"));

    //CComBSTR(intnSize, LPCOLESTR sz);

    CComBSTRstr3(5, (LPCOLESTR)NULL);

    //CComBSTR(intnSize);

    CComBSTRstr4(5);

    //CComBSTR(LPCSTRpSrc);

    CComBSTRstr5("hello,world");

    //CComBSTR(intnSize, LPCSTR sz);

    CComBSTRstr6(5,"hello,world");

    //CComBSTR(REFGUIDsrc);

    static constGUID id_sample =

        { 0x3d8b3644, 0xf90e, 0x4058, { 0x95,0xaf, 0xda, 0x5a, 0xe8, 0x81, 0x8, 0x98 } };

    CComBSTRstr7(id_sample);

 

    //2.複製構造函數

    //CComBSTR(constCComBSTR& src);

    CComBSTRstr8(str2);

 

    //3.析構

    //~CComBSTR(){::SysFreeString(m_str); }

 

    //4.賦值

    //CComBSTR&operator=(const CComBSTR& src){ ... m_str = src.Copy(); ...}

    str3 = str2;

    //CComBSTR&operator=(LPCOLESTR pSrc){ ... m_str = ::SysAllocString(pSrc); ... }

    str8 = LPCOLESTR("hello,world");

    //CComBSTR&operator=(LPCSTR pSrc){ ... m_str = A2WBSTR(pSrc); ... }

    str1 = "hello,world";

    //HRESULTAssignBSTR(const BSTR bstrSrc){ ... }

    BSTR bstrTemp = ::SysAllocString(LPCOLESTR("hello,world"));

    CComBSTRstr9;

    str9.AssignBSTR(bstrTemp);

    //boolLoadString(HINSTANCE hInst, UINT nID);

    //從指定模塊hInst加載指定的字符串資源nID

    //boolLoadString(UINT nID);

    //使用全局變量_AtlBaseModule從當前模塊加載指定的字符串資源nID

 

    //5.字符串連接

    //HRESULTAppend(LPCOLESTR lpsz, int nLen);

    //HRESULTAppend(LPCOLESTR lpsz);

    //HRESULTAppend(LPCSTR);

    //HRESULTAppend(char ch);

    //HRESULTAppend(wchar_t ch);

    //HRESULTAppend(const CComBSTR& bstrSrc);

    //HRESULTAppendBSTR(BSTR p);

    //HRESULTAppendBytes(const char * lpsz, int nLen);

    //CComBSTR&operator+=(const CComBSTR& bstrSrc);

 

    //6.字符串比較

    //bool operator!() const { return (m_str == NULL); }

    //operator<()一共有四個重載版本,後面個都是調用第一個,第一個使用VarBstrCmp進行比較

    //booloperator<(const CComBSTR& bstrSrc) const{ ... }

    //booloperator<(LPCSTR pszSrc) const{ ... }

    //booloperator<(LPCOLESTR pszSrc) const{ ... }

    //booloperator<(LPOLESTR pszSrc) const{ ... }

    //operator>()與operator<()類似

    //operator!=()和operator==()則多重載了一個與NULL比較的版本

 

    //7.其它操作

    //返回長度

    //unsigned intLength() const { return ::SysStringLen(m_str); }

    unsigned intlen = str2.Length();

    //複製操作

    //BSTR Copy() {... }

    //HRESULTCopyTo(BSTR* pbstr);

    //轉換操作

    str2.ToLower();

    str2.ToUpper();

    //HRESULTBSTRToArray(LPSAFEARRAY * ppArray){ ... }

    //HRESULTArrayToBSTR(const SAFEARRAY * pSrc){ ... }

    //清空操作

    str1.Empty();

    //附加和分離BSTR

    //BSTR Detach() {BSTR s = m_str; m_str = NULL; return s; }

    //voidAttach(BSTR src){

    //   if(m_str != src){

    //       ::SysFreeString(m_str);

    //       m_str = src;

    //   }

    //}

 

CString

從簡,使用CString,本質是使用CStringT模板類。

typedefCStringTwchar_t,StrTraitATL<wchar_t,ChTraitsCRT<wchar_t> > > CAtlStringW;

typedefCStringTchar,StrTraitATL<char,ChTraitsCRT<char> > > CAtlStringA;

typedefCStringTTCHAR,StrTraitATL<TCHAR,ChTraitsCRT<TCHAR> > > CAtlString;

         ……

typedefCAtlStringW CStringW;

typedefCAtlStringA CStringA;

typedefCAtlString CString;

                   ……

    template<typenameBaseType,classStringTraits>

    class CStringT :

        public CSimpleStringT……

CStringT繼承CSimpleStringT,該基類提供了很多基本字符串功能;BaseType模板參數用來確定字符類型,數據保存在基類私有成員m_pszData中;StringTraits參數確定資源字符串加載的模塊、字符串管理器以及提供低級的字符操作。ATL提供了默認的字符串管理器,該管理器是一個實現了IAtlStringMgr的具體類CAtlStringMgr。

CStringT採用了類型定義來處理一些語法分支,XCHAR、PXSTR、PCXSTR代表與模板參數一致的字符類型,而YCHAR、PYSTR、PCYSTR相反。比如如果BaseType爲char,則XCHAR代表char,YCHAR代表wchar_t,相應的PXSTR爲LPSTR,PYSTR爲LPWSTR。

基本使用小結如下:

    //CStringT基本使用小結

    //1.構造函數

    //CStringT();

    //explicitCStringT( IAtlStringMgr* pStringMgr );

    //CStringT( constCStringT& strSrc );

    //CStringT( constCThisSimpleString& strSrc );

    //CStringT( constXCHAR* pszSrc );

    //CStringT( constXCHAR* pch, int nLength );

    //CStringT( constXCHAR* pch, int nLength, IAtlStringMgr* pStringMgr );

    //CStringT( PXSTRpszSrc, IAtlStringMgr* pStringMgr );

    //以上例,與之相反的YCHAR和PYSTR也可

    CStringAcaStr1(L"hello,world");

    CStringWcwStr1("hello,world");

    CString cStr1;

    CString cStr2(cStr1);

    CString cStr3("hello,world");

    CString cStr4('a', 5);

 

    //2.賦值

    //CStringT&operator=( const CStringT& strSrc );

    //CStringT&operator=( const CThisSimpleString& strSrc );

    //CStringT&operator=( PCXSTR pszSrc );

    //CStringT&operator=( XCHAR ch );

    //以上兩例,YCHAR和PCYSTR也可

    caStr1 =L'b';

    cwStr1 ='a';

    cStr1 = "hello,world";

    cStr1 = L"hello,world";

 

    //3.字符串連接

    //CStringT&operator+=( const CThisSimpleString& str );

    //CStringT&operator+=( const PCXSTR pszSrc );

    //CStringT&operator+=( const XCHAR ch );

    //以上兩例,PCYSTR和YCHAR也可

    caStr1+= L'a';

    cwStr1+= L"new";

    cStr1 +=cStr2;

    //+運算

    cStr1 + cStr2;

    cStr1 + L'a';

    cwStr1 +'a';

    //Append

    //void Append(PCXSTR pszSrc );

    //void Append(PCXSTR pszSrc, int nLength );

    //void Append(const CSimpleStringT& strSrc );

    //voidAppendChar( XCHAR ch );

    

    //4.轉換

    cStr1.MakeLower();

    cStr1.MakeUpper();

    cStr1.MakeReverse();

 

    //5.比較

    //==  != <  >

    caStr1== L"hello,world";

    cwStr1!= "hello,world";

    cStr1cStr2;

 

    //6.其它操作

    //

    //int Insert( intiIndex, PCXSTR psz )

    //int Insert( intiIndex, XCHAR ch )

    cStr1.Insert(0,'a');

    //

    //從iIndex開始刪除nCount個字符

    //int Delete( intiIndex, int nCount = 1 )

    //刪除所有chRemove字符

    //int Remove(XCHAR chRemove )

    //

    //int Replace(XCHAR chOld, XCHAR chNew )

    //int Replace(PCXSTR pszOld, PCXSTR pszNew )

    //

    //int Find( XCHARch, int iStart = 0 ) const

    //int Find( PCXSTRpszSub, int iStart = 0 ) const

    //int FindOneOf(PCXSTR pszCharSet ) const

    //intReverseFind( XCHAR ch ) const

    //CStringT Left(int nCount ) const

    //CStringT Mid(int iFirst ) const

    //CStringT Mid(int iFirst, int nCount ) const

    //CStringT Right(int nCount ) const

    //XCHARoperator[]( int iChar ) const

    str1[3];

 

    //Trim方法

    //CStringT&Trim()

    //CStringT&Trim( XCHAR chTarget )

    //CStringT&Trim( PCXSTR pszTargets )

    //CStringT&TrimLeft()

    //CStringT&TrimLeft( XCHAR chTarget )

    //CStringT&TrimLeft( PCXSTR pszTargets )

    //CStringT&TrimRight()

    //CStringT&TrimRight( XCHAR chTarget )

    //CStringT&TrimRight( PCXSTR pszTargets )

 

    //按指定字符分割

    //CStringTTokenize( PCXSTR pszTokens, int & iStart ) const

 

    //CStringT格式化

    //void __cdeclFormat( PCXSTR pszFormat, ... );

    //void __cdeclFormat( UINT nFormatID, .. );

 

 

參考資料:

《Windows核心編程》

《深入解析ATL》


轉自:http://blog.csdn.net/jasonblog/article/details/6139669

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章