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