1. 程式人生 > >C++中string和string.h以及cstring,CString的作用和區別

C++中string和string.h以及cstring,CString的作用和區別

1.string與cstring有什麼區別

<string>是C++標準庫標頭檔案,包含了擬容器class std::string的宣告(不過class string事實上只是basic_string<char>的typedef),用於字串操作。
<cstring>是C標準庫標頭檔案<string.h>的C++標準庫版本,包含了C風格字串(NUL即'\0'結尾字串)相關的一些型別和函式的宣告,例如strcmp、strchr、strstr等。<cstring>和<string.h>的最大區別在於,其中宣告的名稱都是位於std名稱空間中的,而不是後者的全域性名稱空間。
看定義就知道了,string是新標準,定義了namespace std;而cstring雖然也是新標,但是定義中包含的是string.h。


string中可以進行+ = += >等運算,而cstring中不能進行相關運算。

1.

#include <cstring>   //不可以定義string s;可以用到strcpy等函式

using   namespace   std;

#include <string>   //可以定義string s;可以用到strcpy等函式
using   namesapce   std;

#include <string.h>   //不可以定義string s;可以用到strcpy等函式

2.

1)檔案cstring,和string.h對應,c++版本的標頭檔案,包含比如strcpy之類的字串處理函式
2)檔案string.h,和cstring對應,c版本的標頭檔案,包含比如strcpy之類的字串處理函式
3)檔案string,包含std::string的定義,屬於STL範疇
4)CString,MFC裡的的字串類

string.h是C語言中字串操作函式的標頭檔案
cstring是c++對C語言中的strcpy之類的函式申明,包含cstring之後,就可以在程式中使用C語言風格的strcpy之類的函式。

string是c++語言中string類模板的申明 
CString是MFC中定義的字串類,MFC中很多類及函式都是以CString為引數的,另外CString類過載了(LPCSTR)運算子,所以如果你在MFC下面使用CString類,就可以直接用CString類做為引數來呼叫需要一個C語言風格字串的win   api函式,編譯器會自動呼叫(LPCSTR)成員函式完成從CString到一個C風格字串的轉換。如果你在MFC下使用C++語言中標準的 string類,那麼在呼叫需要C語言風格的字串為引數的win   api時,你必須顯示呼叫sting.c_str()成員函式,來完成同樣的轉換,也就是說在使用MFC裡,如果用CString類,會比sting類方便那麼一點點。

3.

(1).首先說cstring與string.h:
cstring和string.h其實裡面都是C標準庫提供的東西,某些實現中cstring的內容
就是:  
  namespace   std  
  {  
  #include   <string.h>  
  }  
cstring是C++的組成部分,它可以說是把C的string.h的升級版,但它不是C的組成部分。
所以如果你用的是C++,那麼請用cstring,如果你用的是C請用string.h。

(2).string與cstring: 
一般一個C++庫老的版本帶“.h”副檔名的庫檔案,比如iostream.h,在新標準後的標準庫中都有一個不帶“.h”副檔名的相對應,區別除了後者的好多改進之外,還有一點就是後者的東東都塞進了“std”名字空間中。      
string,它是C++定義的std::string所使用的檔案,是string類的標頭檔案,屬於STL範疇。它有很多對字串操作的方法。

4.string.h是C++標準化(1998年)以前的C++庫檔案,在標準化過程中,為了相容以前,標準化組織將所有這些檔案都進行了新的定義,加入到了標準庫中,加入後的檔名就新增了一個"c"字首並且去掉了.h的字尾名,所以string.h標頭檔案成了cstring標頭檔案。但是其實現卻是相同的或是相容以前的。相當於標準庫組織給它蓋了個章,說“你也是我的標準程式庫的一份子了”

5.cstring代表的是string.h,但是被封裝到了std裡面,譬如呼叫strlen函式,需要寫成std::strlen(yourstr)才行,這個使用方法比較符合C++的標準要求string就是C++標準庫裡面的string模板(確切地說應該是一個特化的模板),但是他同樣包含了C風格字串操作函式的定義(應該是通過包含string.h實現的)string.h就不需要使用名字空間了,這個是C風格字串操作的一個函式庫,strlen,strcpy,strcat,strcmp……都在這裡面了,不過既然是C風格的庫,當然不需要namespace支援了。


2.C++中string和string.h的作用和區別

#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類半點聯絡也沒有,所以並非的“晉級版別”,他們是毫無 聯絡的兩個標頭檔案。

要抵達樓主的目的,比如一同:

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

或許

#include < cstring >#include < string >C++中string和string.h的作用和區別(2)笑談(來自高 質量++)

C++標準庫很大。非常大。難以置信的大。如何個大法?這麼說 吧:在C++標準中,關於標準庫的標準說明佔了密密麻麻300 多頁,這還不包含 標準C 庫,後者只是"作為參看"(老實說,原文便是用的這個詞)包 含在C++庫中。當然,並非總是越大越好,但在如今的情況下,確實越大越好, 因為大的庫會包含許多的功用。標準庫中的功用越多,開發自個的應用程式時能 憑仗的功用就越多。C++庫並非供應了悉數(很明顯的是,沒有供應併發和圖形 使用者介面的支撐),但確實供應了許多。幾乎任何事你都可以求助於它。在歸納 標準庫中有些啥之前,需要介紹一下它是怎樣組織的。因為標準庫中東西如此 之多,你(或象你相同的其他啥人)所選擇的類名或函式名就很有可以和標準 庫中的某個名字相同。為了避免這種情況所構成的名字衝突,實習上標準庫中的 悉數都被放在名字空間std 中(參見條款28)。但這帶來了一個新問題。許多現 有的C++程式碼都依賴於運用了多年的偽標準庫中的功用,例如,宣告在,,等標頭檔案中的功 能。現有軟體沒有關於運用名字空間而進行描寫,如果用std 來包裝標準庫致使 現有程式碼不能用,將是一種廉恥舉動。(這種釜底抽薪的做法會讓現有程式碼的程 序員說出比"廉恥" 更尖銳的話)懾於被激怒的程式設計師會發作的損壞 力,標準委員會決定為包裝了std 的那有些標準庫構件創立新的標頭檔案名。生成 新標頭檔案的方法只是是將現有C++標頭檔案名中的。h 去掉,方法本身不重要,正 如結尾發作的效果不一致也並不重要相同。所以變成了,變成了,等等。關於C 標頭檔案,選用相同的方法,但在每個名字前還要新增一個c.所以C 的變成了,變成了,等等。結尾一點是,舊的C++標頭檔案是官方所敵對運用的(即 ,明晰列出不再支撐),但舊的C 標頭檔案則沒有(以堅持對C 的相容性)。實習 上,編譯器製造商不會間斷對客戶現有軟體供應支撐,所以可以估量,舊的C++ 標頭檔案在將來幾年內仍是會被支撐。

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

舊的C++標頭檔案名如將會繼續被支撐,儘管 它們不在官方標準中。這些標頭檔案的內容不在名字空間std 中。

新的C++ 標頭檔案如包含的根本功用和對應的舊標頭檔案相同,但標頭檔案的 內容在名字空間std 中。(在標準化的過程中,庫中有些有些的細節被修改了, 所以舊標頭檔案和新標頭檔案中的實體不一定完全對應。)

標準C 標頭檔案如繼續被支撐。標頭檔案的內容不在std 中。

具有C 庫功用 的新C++標頭檔案具有如這樣的名字。它們供應的內容和相應的舊C 標頭檔案相同,只是內容在std 中。

所有這些初看有點怪,但不難習氣它 。最大的應戰是把字串標頭檔案理理解:

是舊的C 頭 檔案,對應的是依據char*的字串處置函式;

是對應 於舊C 標頭檔案的std 版別;

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

如果能掌握這些(我相信你能),其他的也就 簡略了



3. string和CString 的比較  

    (一) 概述
  string和CString均是字串模板類,string為標準模板類(STL)定義的字串類,已經納入C++標準之中;
  CString(typedef CStringT<TCHAR, StrTraitMFC<TCHAR>> CString)為Visual C++中最常用的字串類,繼承自CSimpleStringT類,主要應用在MFC和ATL程式設計中,主要資料型別有char(應用於ANSI),wchar_t(unicode),TCHAR(ANSI與unicode均可);
  char*為C程式設計中最常用的字串指標,一般以’\0’為結束標誌;
  (二) 構造
  2 string是方便的,可以從幾乎所有的字串構造而來,包括CString和char*;
  2 CString次之,可以從基本的一些字串變數構造而來,包括char*等;
  2 char*沒有建構函式,僅可以賦值;
  2 舉例:
  char* psz = “joise”;
  CString cstr( psz );
  string str( cstr );
  (三) 運算子過載
  a) operator=
  2 string是最方便的,幾乎可以直接用所有的字串賦值,包括CString和char*;
  2 CString次之,可以直接用些基本的字串賦值,包括char*等;
  2 char*只能由指標賦值,並且是極危險的操作,建議使用strcpy或者memcpy,而且char*在宣告的時候如未賦初值建議先設為NULL,以避免野指標,令你抓狂;
  2 舉例:
  char *psz = NULL;
  psz = new char[10]; //當然,以上的直接寫成char *psz = new char[10];也是一樣
  memset( psz, 0, 10 );
  strcpy( psz, “joise” ); 
  CString cstr;
  cstr = psz;
  string str;
  str = psz;
  str = cstr;
  delete []psz;
  b) operator+
  2 string與CString差不多,可以直接與char*進行加法,但不可以相互使用+運算子,即string str = str + cstr是非法的,須轉換成char*;
  2 char*沒有+運算,只能使用strcat把兩個指標連在一起;
  2 舉例:
  char* psz = “joise”;
  CString cstr = psz;
  cstr = cstr + psz;
  string str = psz;
  str = str + str + psz;
  strcat( psz, psz );
  strcat( psz, cstr );//合法
  strcat( psz, str );//非法,由此可見,CString可自動轉換為const char*,而string不行
  c) operator +=
  2 string是最強大的,幾乎可以與所有的字串變數+=,包括CString和char*;
  2 CString次之,可以與基本的一些字串變數進行+=而來,包括char*等;
  2 char*沒有+=運算子,只能使用strcat把兩個指標連在一起;
  d) operator[]
  2 CString最好,當越界時會丟擲斷言異常;
  2 string與char*下標越界結果未定義;
  2 舉例:
  char* psz = “joise”;
  CString cstr = psz;
  cout << cstr[8];
  string str = psz;
  cout << str[8];
  cout << psz[8];
  e) operator== 、operator!=、operator> 、operator< 、operator>= 、perator<=
  2 CString與string之間不可以進行比較,但均可以與char*進行比較,並且比較的是值,而不是地址;
   cout << ( psz == cstr );
   cout << ( psz == str );
   cout << ( str == psz );
   cout << ( cstr == psz );//以上程式碼返回均為1
  (四) 常用演算法
  a) 查詢
  
  作用
  char*
  string
  CString
  查詢指定值
  strchr
  strstr
  strrstr
  strspn
  find
  Find
  第一個匹配的值  
  fild_first_of
  FindOneOf
  從後面開始查詢
  
  ReserveFind
  指定匹配方式  
  find_if  
  注:find_if中是把範圍內的值挨個代入匹配函式直至返回true
  b) 比較
  
  作用
  char*
  string
  CString
  查詢指定值(區分大小寫)
  strcmp
  strncmp
  strcoll
  _strncoll
  operator<
  operator>
  operator<= 
  operator>=
  operator==
  operator!=
  Collate
  Compare
  查詢指定值(不區分大小寫)
  _stricmp
  _strnicmp
  _stricoll
  _strnicoll
  
  CollateNoCase
  CompareNoCase
  注:返回值如果<0則前面的值小於後面的值,反之亦然
  c) 替換
  
  作用
  char*
  string
  CString
  查詢指定值
  _strset
  _strnset
  replace
  replace_copy
  replace_copy_if
  replace_if
  
  Replace
  d) 插入
  
  作用
  char*
  string
  CString
  查詢指定值

 e) 增加
  
  作用
  char*
  string
  CString
  動態增加值
  strcat
  push
  append
  Append
  AppendChar
  AppendFormat
  f) 擷取
  
  作用
  char*
  string
  CString
  得到部分值
  用下標操作
  substr
  Left
  Mid
  Right
  Truncate
  g) 移除
  
  作用
  char*
  string
  CString
  移除部份值
  
  remove
  Remove
  移除空白值
  RemoveBlanks
  注:此為ATL提供,非C函式
  remove_if
  Trim
  TrimLeft
  TrimRigth
  h) 轉換大小寫
  
  作用
  char*
  string
  CString
  轉換大小寫
  _strlwr
  _strupr
  
  MakeLower
  MakeUpper
  i) 與其他型別轉換
  
  作用
  char*
  string
  CString
  轉化為數字
  atoi
  atod
  atof
  
  Format
  轉化為char*
  
  c_str
  GetBuffer
  GetBufferSetLength
  j) 格式化
  
  作用
  char*
  string
  CString
  格式化
  sprintf
  
  Format
  k) 得到長度
  
  作用
  char*
  string
  CString
  得到長度
  strlen
  length
  GetLength
  得到大小
  
  size
  GetAllocLength
  l) 判斷為空
  
  作用
  char*
  string
  CString
  判斷是否為空
  判斷是否==NULL或者第一個字元是否是’\0’
  empty
  IsEmpty
  m) 重定義大小
  
  作用
  char*
  string
  CString
  重定義大小
  realloc
  new
  resize
  GetBufferSetLength
  n) 釋放資源
  
  作用
  char*
  string
  CString
  釋放
  free
  delete (delete[])
  
  ReleaseBuffer
  ReleaseBufferSetLength
  (五) 安全性
  CString > string > char*;
  (六) 靈活性
  CString > string >char*;
  (七) 可移植性
  char* = string > CString  
  insert
  Insert 

方法一:
CString m_str(_T("qwerg"));
char *chr=new char[m_str.GetLength()+1];
WideCharToMultiByte(CP_ACP,0,m_str.GetBuffer(),-1,chr,m_str.GetLength()+1,NULL,NULL);
string str=chr;
cout<<str;
方法二
CString str = _T("ooqoqoq");  
setlocale(LC_ALL, "chs");
char *p = new char[str.GetLength()+1];
wcstombs(p,str,str.GetLength()+1);
string m_fileName = p;
cout<<m_fileName;

參考: