天天看點

整理:CString類的完美總結&&CString 成員函數用法大全&&string 與 CString 轉化&&<string><string.h> 和<cstring>的差別CString類的完美總結:CString的構造函數string 與 CString 轉化:<string><string.h> 和<cstring>的差別 CString

CString類的完美總結:

①、CString 類對象的初始化:

CString str;

CString str1(_T("abc"));

CString str2 = _T("defg");


TCHAR szBuf[] = _T("kkk");

CString str3(szBuf);

CString str4 = szBuf;


TCHAR *p = _T("1k2");

//TCHAR * 轉換為 CString

CString str5(p);

CString str6 = p;


CString str7(str1);

CString str8 = str7;
           

②、字元串基本操作:

● 長度:GetLength();

CString str(_T("abc"));

int len = str.GetLength(); //len == 3
           

● 是否為空,即不含字元:IsEmpty();

● 清空字元串:Empty();

CString str(_T("abc"));

BOOL mEmpty = str.IsEmpty(); //mEmpty == FALSE

str.Empty();

mEmpty = str.IsEmpty(); //mEmpty == TRUE
           

● 轉換大小寫:MakeUpper、MakeLower

● 轉換順序:MakeReverse

CString str(_T("Abc"));

str.MakeUpper(); //str == ABC

str.MakeLower(); //str == abc

str.MakeReverse(); //str == cba
           

● 字元串的連接配接:+、+=

CString str(_T("abc"));

str = _T("de") + str + _T("kp"); //str == deabckp

str += _T("123"); //str == deabckp123

TCHAR szBuf[] = _T("789");

str += szBuf; //str == deabckp123789
           

● 字元串的比較:==、!=、(<、>、<=、>= 不常用)、Compare(區分大小寫)、CompareNoCase(不區分大小寫)

CString str1(_T("abc"));

CString str2 = _T("aBc");

if (str1 == str2){

MessageBox(_T("str1 等于 str2"));

}else{

MessageBox(_T("str1 不等于 str2"));

}
           

③、字元串的查找:

Find、ReverseFind、FindOneOf 三個函數可以實作字元串的查找操作

Find 從指定位置開始查找指定的字元或者字元串,傳回其位置,找不到傳回 -1;

舉例:

CString str(_T("abcdefg"));

int idx = str.Find(_T("cde"), 0); //idx 的值為2;
           

ReverseFind 從字元串末尾開始查找指定的字元,傳回其位置,找不到傳回 -1,雖然是從後向前查找,但是位置為從開始算起;

CString str(_T("abcdefg"));

int idx = str.ReverseFind('e'); //idx 的值為4;
           

FindOneOf 查找參數中給定字元串中的任意字元,傳回第一次出現的位置,找不到傳回 -1;

CString str(_T("abcabcd"));

int idx = str.FindOneOf(_T("cbd")); //idx 的值為1;
           

④、字元串的替換與删除:

Replace 替換 CString 對象中的指定的字元或者字元串,傳回替換的個數,無比對字元傳回 0;

CString str(_T("abcdabc"));

int num = str.Replace('b', 'k'); //str == akcdakc, num == 2



CString str(_T("abcdabc"));

int num = str.Replace(_T("bc"), _T("kw")); //str == akwdakw, num == 2
           

Remove 删除 CString 對象中的指定字元,傳回删除字元的個數,有多個時都會删除;

CString str(_T("abcdabcb"));

int num = str.Remove('b'); //str == acdac, num == 3
           

Delete 删除 CString 對象中的指定位置的字元,傳回處理後的字元串長度;

CString str(_T("abcd"));

int num = str.Delete(1, 3); //str == a, num == 1
           

⑤、字元串的提取:

Left、Mid、Right 三個函數分别實作從 CString 對象的 左、中、右 進行字元串的提取操作;

CString str(_T("abcd"));

CString strResult = str.Left(2); //strResult == ab

strResult = str.Mid(1); //strResult == bcd

strResult = str.Mid(0, 2); //strResult == ab

strResult = str.Right(2); //strResult == cd
           

⑥、單個字元的修改:

GetAt、SetAt 可以擷取與修改 CString 對象中的單個 TCHAR 類型字元;

操作符也可以擷取 CString 對象中的單個字元,但為隻讀的,不能進行修改;

CString str(_T("abcd"));

str.SetAt(0, 'k'); //str == kbck

TCHAR ch = str.GetAt(2); //ch == c
           

⑦、其他類型與 CString 對象類型的轉換:

● 格式化字元串:Format 方法,實作從 int、long 等數值類型、TCHAR、TCHAR * 等類型向 CString 類型的轉換;

int num = 6;

CString str;

str.Format(_T("%d"), num);
           

● CString 類型向 int 等數值類型、TCHAR * 類型的轉換:

TCHAR *pszBuf = str.GetBuffer();

str.ReleaseBuffer();



TCHAR *p = (LPTSTR)(LPCTSTR)str;



CString str1(_T("123"));

int num = _ttoi(str1);
           

⑧、CString 對象的 Ansi 與 Unicode 轉換:

大家可以直接使用上節課給大家講解的方法,此外這裡給大家介紹一種從 Ansi 轉換到 Unicode 的隐含方法:

//目前工程環境為Unicode

CString str;

str = "abc";

char *p = "defg";

str = p;
           

⑨、 CString 對象字元串所占用的位元組數:

CString str = _T("abc");

錯誤的求法:sizeof(CString)、sizeof(str)

正确的求法:str.GetLength()*sizeof(TCHAR)

⑩、當作為 TCHAR * 類型傳參時,確定申請了足夠用的空間,比如使用 GetModuleFileName 函數;

CString的構造函數

CString( );

例:CString csStr;

CString( const CString& stringSrc );

例:CString csStr("ABCDEF中文123456");

    CString csStr2(csStr);

CString( TCHAR ch, int nRepeat = 1 );

例:CString csStr('a',5);

//csStr="aaaaa"

CString( LPCTSTR lpch, int nLength );

例:CString csStr("abcdef",3);

//csStr="abc"

CString( LPCWSTR lpsz );

例:wchar_t s[]=L"abcdef";

    CString csStr(s);

//csStr=L"abcdef"

CString( const unsigned char* psz );

例:const unsigned char s[]="abcdef";

    const unsigned char* sp=s;

    CString csStr(sp);

//csStr="abcdef"

CString( LPCSTR lpsz );

例:CString csStr("abcdef");

//csStr="abcdef"

int GetLength( ) const;

傳回字元串的長度,不包含結尾的空字元。

例:csStr="ABCDEF中文123456";

    printf("%d",csStr.GetLength());        //16

void MakeReverse( );

颠倒字元串的順序

例:csStr="ABCDEF中文123456";

    csStr.MakeReverse();

    cout<<csStr;                   //654321文中FEDCBA

void MakeUpper( );

将小寫字母轉換為大寫字母

例:csStr="abcdef中文123456";

    csStr.MakeUpper();

    cout<<csStr;                   //ABCDEF中文123456

void MakeLower( );

将大寫字母轉換為小寫字母

例:csStr="ABCDEF中文123456";

    csStr.MakeLower();

    cout<<csStr;                   //abcdef中文123456

int Compare( LPCTSTR lpsz ) const;

區分大小寫比較兩個字元串,相等時傳回0,大于時傳回1,小于時傳回-1

例:csStr="abcdef中文123456";

    csStr2="ABCDEF中文123456";

    cout<<csStr.CompareNoCase(csStr2);              //0

int CompareNoCase( LPCTSTR lpsz ) const;

不區分大小寫比較兩個字元串,相等時傳回0,大于時傳回1,小于時傳回-1

例:csStr="abcdef中文123456";

    csStr2="ABCDEF中文123456";

    cout<<csStr.CompareNoCase(csStr2);              //-1

int Delete( int nIndex, int nCount = 1 )

删除字元,删除從下标nIndex開始的nCount個字元

例:csStr="ABCDEF";

    csStr.Delete(2,3);

    cout<<csStr;               // ABF

//當nIndex過大,超出對像所在記憶體區域時,函數沒有任何操作。

//當nIndex為負數時,從第一個字元開始删除。

//當nCount過大,導緻删除字元超出對像所在記憶體區域時,會發生無法預料的結果。

//當nCount為負數時,函數沒有任何操作。

int Insert( int nIndex, TCHAR ch )

int Insert( int nIndex, LPCTSTR pstr )

在下标為nIndex的位置,插入字元或字元串。傳回插入後對象的長度

例:csStr="abc";

    csStr.Insert(2,'x');

    cout<<csStr;                      //abxc

    csStr="abc";

    csStr.Insert(2,"xyz");

    cout<<csStr;                      //abxyzc

//當nIndex為負數時,插入在對象開頭

//當nIndex超出對象末尾時,插入在對象末尾

int Remove( TCHAR ch );

移除對象内的指定字元。傳回移除的數目

例:csStr="aabbaacc";

    csStr.Remove('a');

    cout<<csStr;                      //bbcc

int Replace( TCHAR chOld, TCHAR chNew );

int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );

替換字串

例:csStr="abcdef";

    csStr.Replace('a','x');

    cout<<csStr;                     //xbcdef

    csStr="abcdef";

    csStr.Replace("abc","xyz");

    cout<<csStr;                     //xyzdef

void TrimLeft( );

void TrimLeft( TCHAR chTarget );

void TrimLeft( LPCTSTR lpszTargets );

從左删除字元,被删的字元與chTarget或lpszTargets比對,一直删到第一個不比對的字元為止

例:csStr="aaabaacdef";

    csStr.TrimLeft('a');

    cout<<csStr;                 //baacdef

    csStr="aaabaacdef";

    csStr.TrimLeft("ab");

    cout<<csStr;                 //cdef

//無參數時删除空格

void TrimRight( );

void TrimRight( TCHAR chTarget );

void TrimRight( LPCTSTR lpszTargets );

從右删除字元,被删的字元與chTarget或lpszTargets比對,一直删到第一個不比對的字元為止

例:csStr="abcdeaafaaa";

    csStr.TrimRight('a');

    cout<<csStr;                //abcdeaaf

    csStr="abcdeaafaaa";

    csStr.TrimRight("fa");

    cout<<csStr;                 //abcde

//無參數時删除空格

void Empty( );

清空

例:csStr="abcdef";

    csStr.Empty();

    printf("%d",csStr.GetLength());     //0

BOOL IsEmpty( ) const;

測試對象是否為空,為空時傳回零,不為空時傳回非零

例:csStr="abc";

    cout<<csStr.IsEmpty();          //0;

    csStr.Empty();

    cout<<csStr.IsEmpty();          //1;

int Find( TCHAR ch ) const;

int Find( LPCTSTR lpszSub ) const;

int Find( TCHAR ch, int nStart ) const;

int Find( LPCTSTR pstr, int nStart ) const;

查找字串,nStart為開始查找的位置。未找到比對時傳回-1,否則傳回字串的開始位置

例:csStr="abcdef";

    cout<<csStr.Find('b');        //1

    cout<<csStr.Find("de");       //3

    cout<<csStr.Find('b',3);      //-1

    cout<<csStr.Find('b',0);      //1

    cout<<csStr.Find("de",4);     //-1

    cout<<csStr.Find("de",0);     //3

//當nStart超出對象末尾時,傳回-1。

//當nStart為負數時,傳回-1。

int FindOneOf( LPCTSTR lpszCharSet ) const;

查找lpszCharSet中任意一個字元在CString對象中的比對位置。未找到時傳回-1,否則傳回字串的開始位置

例:csStr="abcdef";

    cout<<csStr.FindOneOf("cxy");        //2

CString SpanExcluding( LPCTSTR lpszCharSet ) const;

傳回對象中與lpszCharSet中任意比對的第一個字元之前的子串

例:csStr="abcdef";

    cout<<csStr.SpanExcluding("cf");     //ab

CString SpanIncluding( LPCTSTR lpszCharSet ) const;

從對象中查找與lpszCharSe中任意字元不比對的字元,并傳回第一個不比對字元之前的字串

例:csStr="abcdef";

    cout<<csStr.SpanIncluding("fdcba");     //abcd

int ReverseFind( TCHAR ch ) const;

從後向前查找第一個比對,找到時傳回下标。沒找到時傳回-1

例:csStr="abba";

    cout<<csStr.ReverseFind('a');         //3

void Format( LPCTSTR lpszFormat, ... );

void Format( UINT nFormatID, ... );

格式化對象,與C語言的sprintf函數用法相同

例:csStr.Format("%d",13);

    cout<<csStr;                        //13

TCHAR GetAt( int nIndex ) const;

傳回下标為nIndex的字元,與字元串的[]用法相同

例:csStr="abcdef";

    cout<<csStr.GetAt(2);              //c

//當nIndex為負數或超出對象末尾時,會發生無法預料的結果。

void SetAt( int nIndex, TCHAR ch );

給下标為nIndex的字元重新指派

例:csStr="abcdef";

    csStr.SetAt(2,'x');

    cout<<csStr;                       //abxdef

//當nIndex為負數或超出對象末尾時,會發生無法預料的結果。

CString Left( int nCount ) const;

從左取字串

例:csStr="abcdef";

    cout<<csStr.Left(3);            //abc

//當nCount等于0時,傳回空。

//當nCount為負數時,傳回空。

//當nCount大于對象長度時,傳回值與對象相同。

CString Right( int nCount ) const;

從右取字串

例:csStr="abcdef";

    cout<<csStr.Right(3);            //def

//當nCount等于0時,傳回空。

//當nCount為負數時,傳回空。

//當nCount大于對象長度時,傳回值與對象相同。

CString Mid( int nFirst ) const;

CString Mid( int nFirst, int nCount ) const;

從中間開始取字串

例:csStr="abcdef";

    cout<<csStr.Mid(2);            //cdef

    csStr="abcdef";

    cout<<csStr.Mid(2,3);          //cde

//當nFirst為0和為負數時,從第一個字元開始取。

//當nFirst等于對象末尾時,傳回空字串。

//當nFirst超出對象末尾時,會發生無法預料的結果。

//當nCount超出對象末尾時,傳回從nFirst開始一直到對象末尾的字串

//當nCount為0和為負數時,傳回空字串。

LPTSTR GetBuffer( int nMinBufLength );

申請新的空間,并傳回指針

例:csStr="abcde";

    LPTSTR pStr=csStr.GetBuffer(10);

    strcpy(pStr,"12345");

    csStr.ReleaseBuffer();

    pStr=NULL;

    cout<<csStr                  //12345

//使用完GetBuffer後,必須使用ReleaseBuffer以更新對象内部資料,否則會發生無法預料的結果。

void ReleaseBuffer( int nNewLength = -1 );

使用GetBuffer後,必須使用ReleaseBuffer以更新對象内部資料

例:csStr="abc";

    LPTSTR pStr=csStr.GetBuffer(10);

    strcpy(pStr,"12345");

    cout<<csStr.GetLength();        //3(錯誤的用法)

    csStr.ReleaseBuffer();

    cout<<csStr.GetLength();        //5(正确)

    pStr=NULL;

//CString對象的任何方法都應在ReleaseBuffer之後調用

LPTSTR GetBufferSetLength( int nNewLength );

申請新的空間,并傳回指針

例:csStr="abc";

    csStr.GetBufferSetLength(20);

    cout<<csStr;                   //abc

    count<<csStr.GetLength();      //20;

    csStr.ReleaseBuffer();

    count<<csStr.GetLength();      //3;

//使用GetBufferSetLength後可以不必使用ReleaseBuffer。

string 與 CString 轉化:

都通過基本類型來轉換即可:

CString可以轉換為基本類型LPCTSTR,LPCTSTR根據項目編碼可以是const char*或者const wchar_t*;string可以用c_str()轉換為const char*,stringw可以用c_str()轉換為const w_char*。而CString和string/w都重載了=指派操作符,可以把char*或者wchar_t*字元串指派給CString或者string/w類型的變量,或者調用其構造函數。

string to CString比較簡單

string str="abcde";
   CString cstr(str.c_str());
           

CString to string,要看你的CString用的是UNICODE還是非UNICODE,

非UNICODE就簡單了

CString cs="abcde";
   string str(cs.GetBuffer(cs.GetLength()));
           

UNICODE就麻煩點

需要轉換一下才行,給個函數你用

CString cs=_T("abcde");
string str=CGeneralUtility::WChar2Ansi(cs.GetBuffer(cs.GetLength()));
string CUtility::WChar2Ansi(LPCWSTR pwszSrc)
{
	int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
	if (nLen<= 0)	 return std::string("");
	char* pszDst = new char[nLen];
	if (NULL == pszDst) 	return std::string("");
	WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
	pszDst[nLen -1] = 0;
	std::string strTemp(pszDst);
	delete [] pszDst;
	return strTemp;
}
           

1,string -> CString

CString.format("%s", string.c_str());

2,char -> string

string s(char *);

3,CString -> string

string s(CString.GetBuffer());

GetBuffer()後一定要ReleaseBuffer(),否則就沒有釋放緩沖區所占的空間.

<string><string.h> 和<cstring>的差別

#include <string.h >
  void main()
  {
	  string aaa = " abcsd d " ;
	  printf( " looking for abc from abcdecd %s\n " ,
	  (strcmp(aaa, " abc " )) ? " Found " : " Not Found " );
  }
           

  不能正确執行,提示說是string類型沒有定義

  而下面:

  #include <string>
  using namespace std;
  void main()
  {
	  string aaa = " abcsd d " ;
	  printf( " looking for abc from abcdecd %s\n " ,
	  (strcmp(aaa, " abc " )) ? " Found " : " Not Found " );
  }
           

  這裡的string編譯器就認識了,但是strcmp就不認識了呢?

  一般一個C++的老的帶“。h”擴充名的庫檔案,比如iostream.h,在新标準後的标準庫中都有一個不帶“。h”擴充名的相對應,差別除了後者的好多改進之外,還有一點就是後者的東東都塞進了“std”名字空間中。

  但唯獨string特别。

  問題在于C++要相容C的标準庫,而C的标準庫裡碰巧也已經有一個名字叫做“string.h”的頭檔案,包含一些常用的C字元串處理函數,比如樓主提到的strcmp.

  這個頭檔案跟C++的string類半點關系也沒有,是以<string>并非<string.h>的“更新版本”,他們是毫無關系的兩個頭檔案。

  要達到樓主的目的,比如同時:

  #include <string .h>
  #include <string>
  using namespace std;
           

  或者

  #include < cstring >
  #include < string >
           

  其中<cstring>是與C标準庫的<string.h>相對應,但裹有std名字空間的版本。

  笑談(來自高品質++)

  C++标準庫很大。非常大。難以置信的大。怎麼個大法?這麼說吧:在C++标準中,關于标準庫的規格說明占了密密麻麻300 多頁,這還不包括标準C 庫,後者隻是"作為參考"(老實說,原文就是用的這個詞)包含在C++庫中。當然,并非總是越大越好,但在現在的情況下,确實越大越好,因為大的庫會包含大量的功能。标準庫中的功能越多,開發自己的應用程式時能借助的功能就越多。C++庫并非提供了一切(很明顯的是,沒有提供并發和圖形使用者接口的支援),但确實提供了很多。幾乎任何事你都可以求助于它。在歸納标準庫中有些什麼之前,需要介紹一下它是如何組織的。因為标準庫中東西如此之多,你(或象你一樣的其他什麼人)所選擇的類名或函數名就很有可能和标準庫中的某個名字相同。為了避免這種情況所造成的名字沖突,實際上标準庫中的一切都被放在名字空間std 中(參見條款28)。但這帶來了一個新問題。無數現有的C++代碼都依賴于使用了多年的僞标準庫中的功能,例如,聲明在<iostream.h>,<complex.h>,<limits.h>等頭檔案中的功能。現有軟體沒有針對使用名字空間而進行設計,如果用std 來包裝标準庫導緻現有代碼不能用,将是一種可恥行為。(這種釜底抽薪的做法會讓現有代碼的程式員說出比"可恥" 更難聽的話)懾于被激怒的程式員會産生的破壞力,标準委員會決定為包裝了std 的那部分标準庫構件建立新的頭檔案名。生成新頭檔案的方法僅僅是将現有C++頭檔案名中的。h 去掉,方法本身不重要,正如最後産生的結果不一緻也并不重要一樣。是以<iostream.h>變成了<iostream>,<complex.h>變成了<complex>,等等。對于C 頭檔案,采用同樣的方法,但在每個名字前還要添加一個c.是以C 的<string.h>變成了<cstring>,<stdio.h>變成了<cstdio>,等等。最後一點是,舊的C++頭檔案是官方所反對使用的(即,明确列出不再支援),但舊的C 頭檔案則沒有(以保持對C 的相容性)。實際上,編譯器制造商不會停止對客戶現有軟體提供支援,是以可以預計,舊的C++頭檔案在未來幾年内還是會被支援。

  是以,實際來說,下面是C++頭檔案的現狀:

  舊的C++頭檔案名如<iostream.h>将會繼續被支援,盡管它們不在官方标準中。這些頭檔案的内容不在名字空間std 中。

  新的C++頭檔案如<iostream>包含的基本功能和對應的舊頭檔案相同,但頭檔案的内容在名字空間std 中。(在标準化的過程中,庫中有些部分的細節被修改了,是以舊頭檔案和新頭檔案中的實體不一定完全對應。)

  标準C 頭檔案如<stdio.h>繼續被支援。頭檔案的内容不在std 中。

  具有C 庫功能的新C++頭檔案具有如<cstdio>這樣的名字。它們提供的内容和相應的舊C 頭檔案相同,隻是内容在std 中。

  所有這些初看有點怪,但不難習慣它。最大的挑戰是把字元串頭檔案理清楚:

  <string.h>是舊的C 頭檔案,對應的是基于char*的字元串處理函數;

  <cstring>是對應于舊C 頭檔案的std 版本;

  <string>是包裝了std 的C++頭檔案,對應的是新的string 類。

 

CString

CString does not have a base class.

A CString object consists of a variable-length sequence of characters. CString provides functions and operators using a syntax similar to that of Basic. Concatenation and comparison operators, together with simplified memory management, make CStringobjects easier to use than ordinary character arrays.

CString is based on the TCHAR data type. If the symbol _UNICODE is defined for your program, TCHAR is defined as typewchar_t, a 16-bit character type; otherwise, it is defined as char, the normal 8-bit character type. Under Unicode, then,CString objects are composed of 16-bit characters. Without Unicode, they are composed of 8-bit char type.

When not using _UNICODE, CString is enabled for multibyte character sets (MBCS, also known as double-byte character sets, DBCS). Note that for MBCS strings, CString still counts, returns, and manipulates strings based on 8-bit characters, and your application must interpret MBCS lead and trail bytes itself.

CString objects also have the following characteristics:

  • CString objects can grow as a result of concatenation operations.
  • CString objects follow “value semantics.” Think of a CString object as an actual string, not as a pointer to a string. 
  • You can freely substitute CString objects for const char* and LPCTSTR function arguments.
  • A conversion operator gives direct access to the string’s characters as a read-only array of characters (a C-style string).

Tip   Where possible, allocate CString objects on the frame rather than on the heap. This saves memory and simplifies parameter passing.

CString assists you in conserving memory space by allowing two strings sharing the same value also to share the same buffer space.  However, if you attempt to change the contents of the buffer directly (not using MFC), you can alter both strings unintentionally. CString provides two member functions, CString::LockBuffer and CString::UnlockBuffer, to help you protect your data.  When you call LockBuffer, you create a copy of a string, then set the reference count to -1, which "locks" the buffer. While the buffer is locked, no other string can reference the data in that string, and the locked string will not reference another string. By locking the string in the buffer, you ensure that the string’s exclusive hold on the data will remain intact. When you have finished with the data, call UnlockBuffer to reset the reference count to 1.

For more information, see the https://msdn.microsoft.com/en-us/library/aa296565(v=vs.60).aspx and articles in Visual C++ Programmer’s Guide and https://msdn.microsoft.com/en-us/library/2ewd52wf(v=vs.60).aspx in the Run-Time Library Reference.

#include <afx.h>

Class Members |  Hierarchy Chart

Sample   https://msdn.microsoft.com/en-us/library/ms386443(v=vs.60).aspx

See Also   In Visual C++ Programmer’s Guide: , , https://msdn.microsoft.com/en-us/library/aa296561(v=vs.60).aspx , ,