
1. 什么是string在C中字符串有兩種表示方式C風(fēng)格字符串C-style stringC標(biāo)準(zhǔn)庫提供的string類C語言中使用字符數(shù)組表示字符串char str[] hello;本質(zhì)上h e l l o \0字符串末尾需要一個(gè)\0表示結(jié)束。但是C風(fēng)格字符串存在很多問題需要手動管理空間容易發(fā)生越界字符串拼接復(fù)雜容易造成內(nèi)存泄漏例如char str1[20] hello; char str2[] world; strcat(str1, str2);程序員必須提前考慮數(shù)組空間是否足夠。C提供了std::string類解決這些問題。使用#include iostream #include string using namespace std; int main() { string s hello; cout s endl; return 0; }輸出hellostring本質(zhì)上是一個(gè)管理字符數(shù)組的類。它幫我們完成動態(tài)擴(kuò)容內(nèi)存釋放字符串拼接查找替換長度管理2. string的底層結(jié)構(gòu)string內(nèi)部大致包含class string { private: char* _str; // 指向字符串空間 size_t _size; // 當(dāng)前有效字符數(shù)量 size_t _capacity; // 容量 };例如string s hello;內(nèi)存類似_str | v ------------------- | h | e | l | l | o | \0 | ------------------- size 5 capacity 5注意size表示有效字符數(shù)量。capacity表示當(dāng)前申請的空間大小。例如string shello; couts.size()endl; couts.capacity()endl;可能輸出5 15說明雖然字符串只有5個(gè)字符但是內(nèi)部可能提前開辟15個(gè)空間。3. string的構(gòu)造函數(shù)3.1 默認(rèn)構(gòu)造創(chuàng)建空字符串string s;相當(dāng)于3.2 使用字符串初始化string s(hello);或者string shello;3.3 拷貝構(gòu)造string s1hello; string s2(s1);結(jié)果s1: hello s2: hello兩個(gè)對象內(nèi)容一樣。3.4 創(chuàng)建n個(gè)相同字符格式string(size_t n,char c);例如string s(5,a); couts;輸出aaaaa4. string容量相關(guān)接口size()返回字符串長度string shello; couts.size();輸出5length()功能和size一樣couts.length();推薦size()因?yàn)镾TL容器統(tǒng)一使用size。capacity()查看容量string shello; couts.capacity();empty()判斷是否為空string s; if(s.empty()) { cout空字符串; }clear()清空字符串string shello; s.clear(); couts;結(jié)果注意clear只是清除內(nèi)容。不會釋放空間。例如string shello; couts.capacity(); s.clear(); couts.capacity();容量通常不變。5. string訪問字符operator[]最常用string shello; couts[0];輸出h修改s[0]H; couts;結(jié)果Helloat()和[]類似couts.at(0);區(qū)別[]越界不會檢查。at():越界會拋異常。例如string shello; couts.at(100);會產(chǎn)生out_of_range異常6. string遍歷方法1for循環(huán)string shello; for(size_t i0;is.size();i) { couts[i] ; }輸出h e l l o方法2范圍forC11支持for(auto ch:s) { coutch; }方法3迭代器string shello; string::iterator its.begin(); while(it!s.end()) { cout*it; it; }7. string拼接operator最簡單string s1hello; string s2world; string s3s1s2; couts3;輸出helloworldappend()追加字符串string shello; s.append( world); couts;輸出hello worldpush_back()尾插一個(gè)字符string shello; s.push_back(!); couts;輸出hello!注意push_back只能插入一個(gè)字符。錯誤s.push_back(abc);8. string插入insert()格式insert(pos,string)例如string shello; s.insert(5, world); couts;結(jié)果hello world9. string刪除erase()刪除指定位置string shello; s.erase(1,2); couts;過程刪除e l結(jié)果hlo格式erase(pos,len)刪除最后一個(gè)字符s.pop_back();例如string shello; s.pop_back(); couts;輸出hell10. string查找find()查找字符串string shello world; size_t poss.find(world); coutpos;輸出6如果找不到返回string::npos例如if(s.find(abc)string::npos) { cout不存在; }rfind()從后往前查找string shello hello; couts.rfind(hello);輸出611. string替換replace()格式replace(pos,len,string)例如string shello; s.replace(0,5,world); couts;結(jié)果world12. string截取子串substr()格式substr(pos,len)例如string shello world; string subs.substr(6,5); coutsub;輸出world13. string和C字符串轉(zhuǎn)換string轉(zhuǎn)char*不能直接string shello; char* ps;錯誤。使用s.c_str();例如string shello; printf(%s,s.c_str());char*轉(zhuǎn)string直接char str[]hello; string sstr;即可。14. string的擴(kuò)容機(jī)制當(dāng)字符串空間不足時(shí)舊空間 | v [hello] 插入: [hello world] 重新申請更大空間 復(fù)制數(shù)據(jù) 釋放舊空間類似vector。擴(kuò)容通常是1.5倍 或者 2倍不同編譯器實(shí)現(xiàn)不同。例如string s; for(int i0;i100;i) { s.push_back(a); couts.capacity()endl; }可以觀察容量變化。15. string為什么比char數(shù)組方便char數(shù)組char a[100]; strcpy(a,hello); strcat(a,world);問題容易越界不知道長度需要手動管理stringstring shello; sworld;優(yōu)勢自動管理內(nèi)存接口豐富安全性更高支持STL算法16. string使用注意事項(xiàng)1. size返回unsigned類型例如錯誤for(int is.size()-1;i0;i--)因?yàn)閟ize_t是無符號類型可能導(dǎo)致死循環(huán)。推薦for(int i(int)s.size()-1;i0;i--)2. 修改字符串不能越界錯誤string shello; s[10]a;屬于非法訪問。3. 不要頻繁拼接大字符串例如string s; for(int i0;i100000;i) { shello; }可能頻繁擴(kuò)容。優(yōu)化s.reserve(500000);提前開空間。17. reserve和resize區(qū)別這是string里面非常重要的知識。reserve()改變?nèi)萘縮tring s; s.reserve(100);結(jié)果capacity100 size0不會初始化字符。resize()改變有效字符數(shù)量string s; s.resize(10);結(jié)果size10里面產(chǎn)生10個(gè)\0。區(qū)別接口改變是否初始化reserve容量否resize大小是18. string總結(jié)功能接口長度size()容量capacity()清空clear()判斷為空empty()訪問字符[]、at()尾插字符push_back()刪除尾字符pop_back()拼接、append()插入insert()刪除erase()查找find()替換replace()截取substr()預(yù)留空間reserve()調(diào)整大小resize()總結(jié)std::string是C中最常用的字符串類它本質(zhì)上是一個(gè)動態(tài)管理字符數(shù)組的類。學(xué)習(xí)string不僅是學(xué)習(xí)幾個(gè)接口更重要的是理解string如何管理內(nèi)存size和capacity區(qū)別擴(kuò)容機(jī)制深淺拷貝問題STL容器設(shè)計(jì)思想掌握string以后可以為后續(xù)學(xué)習(xí)vectorlistmapunordered_mapSTL算法打下非常好的基礎(chǔ)。一句話總結(jié)C語言告訴我們字符串是什么C string告訴我們?nèi)绾蝺?yōu)雅、安全、高效地管理字符串。