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;
參考: