昆明企業(yè)自助建站系統(tǒng)百度官網(wǎng)客服
緒論
????????放棄時(shí)間的人,時(shí)間也會(huì)放棄他?!勘葋?; 本篇章是關(guān)于string類內(nèi)一些函數(shù)的介紹以及使用方法,都是我們編程必須掌握的基礎(chǔ)!
?
全文共7000字左右.
話不多說安全帶系好,發(fā)車?yán)?strong>(建議電腦觀看)。
附:紅色,部分為重點(diǎn)部分;藍(lán)顏色為需要記憶的部分(不是死記硬背哈,多敲);黑色加粗或者其余顏色為次重點(diǎn);黑色為描述需要
思維導(dǎo)圖:
?
要XMind思維導(dǎo)圖文件的話可以私信哈
目錄
1.STL
2.string以及string的基本使用
2.1string的構(gòu)造函數(shù)
2.2sting的賦值運(yùn)算符重載?
2.3string的append追加函數(shù)
2.4 string的+=運(yùn)算符重載
2.5string的operator[ ]運(yùn)算符重載
2.6迭代器iterator?編輯
2.6.1逆向迭代器reverse_iterator
2.6.2 const_迭代器
3.string類對(duì)象的容量操作的接口函數(shù)
3.1reserve
3.2resize
3.3strink_to_fit
4.對(duì)string空間的元素訪問的接口函數(shù)
4.1operator[]
5.修改string的內(nèi)容的接口函數(shù)
5.1assign
5.2insert
5.3erase
6.對(duì)字符串操作的一些接口
6.1c_str
6.2find
6.3rfind
6.4 find_first_of 、find_last_of
7.string中的非成員函數(shù)重載
7.1一些常用的運(yùn)算符函數(shù)重載
7.1.1比較類運(yùn)算符重載
7.1.2string的 operator +
7.1.3 getline
7.2 把字符串與其他類型的相互轉(zhuǎn)換
1.STL
知識(shí)點(diǎn):
STL:是C++標(biāo)準(zhǔn)庫的重要組成部分,不僅是一個(gè)可復(fù)用的組件庫,還是一個(gè)包羅數(shù)據(jù)結(jié)構(gòu)與算法的軟件框架。
- STL有好幾個(gè)版本:
- 原始版本,由惠普實(shí)驗(yàn)室的兩位大佬完成的(也稱為 HP 版本)
- P.J. 版本 : 它是由P.J. Plauger 開發(fā)完成的。繼承自HP版本,后主要被微軟使用,缺點(diǎn):可讀性低,符號(hào)命名奇怪
- RW 版本 ,后面因?yàn)楦偁幉贿^微軟而倒閉(就不過多敘述)
- SGI 版本,繼承自 HP 版本 ,被GCC(Linux)采用,可移植性強(qiáng),命名風(fēng)格和編程風(fēng)格都比較好 , 有著良好的閱讀性,后面我們主要學(xué)習(xí)這個(gè)版本的STL源碼?
- STL的六大組件
- 算法(swap、find、sort ...)
- 容器(數(shù)據(jù)結(jié)構(gòu))(string、vector、list、map ...)
- 迭代器(iterator、const_iterator 、....)
- 配接器(stack、queue、...)
- 空間配置器(內(nèi)存池)(allocation)
- 仿函數(shù)(less、greater)
2.string以及string的基本使用
知識(shí)點(diǎn):
string他像是一個(gè)數(shù)據(jù)結(jié)構(gòu),管理其字符串的增刪查改
細(xì)節(jié):
我們?cè)趯W(xué)習(xí)的時(shí)候就主要學(xué)習(xí)其中比較重要的部分,因?yàn)閷?duì)于這些庫實(shí)現(xiàn)的是比較全面,可能有過多的分支,我們并不需要全部掌握,因?yàn)閷W(xué)的過多也不一定好事,我們只需要大概的有個(gè)印象即可,到時(shí)候假如要用到的時(shí)候,我們可以去查文檔。
這里推薦一個(gè)可以查看c++文檔的網(wǎng)址:https://cplusplus.com
本章主要通過代碼實(shí)例的形式去掌握語法,我們需要多去使用這樣才能更好的去記住他們
其中以下函數(shù)的使用方法和正常創(chuàng)建的類對(duì)象中的函數(shù)的使用方法是一樣的,可以把?string 看成是一個(gè)類。
2.1string的構(gòu)造函數(shù)
從上圖可以發(fā)現(xiàn),string的構(gòu)造函數(shù)在庫中重載的實(shí)現(xiàn)了很多種(后面還有許多的函數(shù)他們同樣也都是重載了許多函數(shù),并且其參數(shù)也差不多所以我們能類比的進(jìn)行學(xué)習(xí)),他們都有對(duì)應(yīng)的應(yīng)用場景,我們可以根據(jù)不同的情況去對(duì)應(yīng)著使用(但沒必要全部都熟系掌握)。
功能:初始化對(duì)象
用法如下(請(qǐng)單擊圖片放大觀看):
?再通過實(shí)操來對(duì)其進(jìn)行掌握(建議自己看后再寫一遍),具體如下:
?#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<string> using namespace std;int main() {string st;//構(gòu)造為空string st1("hello world");//將hello world字符串給對(duì)象string st2(st1);//拷貝構(gòu)造st1給對(duì)象string st3(st1, 6, 5);//從st1 的下標(biāo)為6的位置處向后的5個(gè)字符給對(duì)象string st4(st1, 6);//在第三個(gè)參數(shù)有缺省值,所以不一定需要寫第三個(gè)參數(shù)npos是一個(gè)無符號(hào)的-1也就是整形的最大值,并且規(guī)定了此處的構(gòu)造函數(shù)當(dāng)npos的長度大于字符串的長度就會(huì)直接打印剩下的全部string st5("hello world",5);//提取c字符串中的前5個(gè)元素給對(duì)象string st6(10, ' * ');//創(chuàng)建10個(gè)*給對(duì)象cout << st <<endl;cout << st1 <<endl;cout << st2 <<endl;cout << st3 <<endl;cout << st4 <<endl;cout << st5 <<endl;cout << st6 <<endl;}
?運(yùn)行結(jié)果:
?
附:string的析構(gòu)函數(shù)接口并不用調(diào)用,程序結(jié)束自動(dòng)歸還操作系統(tǒng),所以就不寫了
2.2sting的賦值運(yùn)算符重載?
?
功能:給類對(duì)象進(jìn)行賦值操作
用法:對(duì)應(yīng)著重載函數(shù)如下代碼:
????string st7("張三");string st8("李四");cout << st7 << endl;st7 = "張三豐";//賦值成一個(gè)字符串cout << st7 << endl;st7 = 'z';//賦值為一個(gè)字符cout << st7 << endl;st7 = st8;//拷貝構(gòu)造cout << st7 << endl;
運(yùn)行結(jié)果:
????(可以把它當(dāng)成內(nèi)置類型一樣的去使用)。
2.3string的append追加函數(shù)
?
功能:其重載的函數(shù)的大概用法和前面的構(gòu)造函數(shù)重載的差不多,只不過此處是追加(就不一 一展示了,主要還是用到第3個(gè),在this指針指向的對(duì)象后面追加字符串)。
具體如下:
?
2.4 string的+=運(yùn)算符重載
?
功能:也是一個(gè)追加類型的函數(shù)(他比追加函數(shù)更加好用,一般就用+=替代append)
用法如下:
?
附:并且對(duì)于上面這些在后面增加字符的情況都不需要我們?nèi)ヅ袛嗍欠裥枰獢U(kuò)容,編譯器都會(huì)幫我們自動(dòng)完成當(dāng)申請(qǐng)空間不夠時(shí)的擴(kuò)容。
2.5string的operator[ ]運(yùn)算符重載
功能:通過operator[ ] 運(yùn)算符 ,我們就能自由的訪問到對(duì)象字符串中的各個(gè)元素了。
具體如下:
?
附:
其中注意的是st.size()他和strlen()?用法是一樣的都不算\0的,
并且因?yàn)槠浞祷刂凳瞧湟?#xff0c;所以對(duì)于使用[ ]時(shí)我們就能去改變其中字符串的內(nèi)容。
如下:此時(shí)我們用的就像內(nèi)置類型一樣,但是我們始終要記得他們底層是不一樣的!
?
2.6迭代器iterator
- 迭代器類似于一個(gè)指針,可以用于任何容器,并且能對(duì)容器內(nèi)的數(shù)據(jù)進(jìn)行訪問和修改
?
- 對(duì)此就要提之前講過的范圍for,其實(shí)范圍for的底層就是用迭代器來實(shí)現(xiàn)的,所以說只要容器滿足迭代器就能使用范圍for。
?
- 對(duì)于算法來說他的本質(zhì)是對(duì)數(shù)據(jù)進(jìn)行修改的(排序的),但是因?yàn)?span style="color:#fe2c24;">容器(數(shù)據(jù))類的對(duì)象都是私有的所以為了使用到其內(nèi)部的數(shù)據(jù),就需要借用迭代器。?
- 證明其容器能使用迭代器
?
- 對(duì)此因?yàn)闈M足迭代器所以就能去用算法和范圍for(reverse逆置算法的參數(shù)需要左閉右開的數(shù)據(jù))
?
?附:
?
其中的begin、end是用來找到字符串對(duì)象的開始和結(jié)尾的并且返回迭代器類型。
2.6.1逆向迭代器reverse_iterator
其用法幾乎一樣,但有幾點(diǎn)需要去注意一下
在寫開始的時(shí)候就需要用rbegin,結(jié)束處為rend,這樣就能從后往前找數(shù)據(jù)
?
此時(shí)能很好的看出begin(rbegin)指向閉區(qū)間,而end(rend)指向開區(qū)間(沒用的空間),所以對(duì)于逆向迭代器來說此時(shí)范圍for就不行了,因?yàn)?span style="color:#fe2c24;">范圍for的底層是一個(gè)正向的迭代器
具體如下:
?
2.6.2 const_迭代器
下面通過實(shí)際情況來進(jìn)行對(duì)const_迭代器的解釋:
此處出錯(cuò)的原因是因?yàn)閭鱽淼膕t是用const類型接收的所以不能用常規(guī)的迭代器const修飾即(對(duì)象是一個(gè)const類型時(shí)就需要用const_iterator)
?
此時(shí)就需要使用到const迭代器:
?
若是逆序的迭代器同理需要用加上const
?
下面是一些會(huì)更加具體的去寫string
3.string類對(duì)象的容量操作的接口函數(shù)
知識(shí)點(diǎn):?
string并不屬于容器,而是在標(biāo)準(zhǔn)庫中的(因?yàn)閟tring產(chǎn)生的比stl更早)
- 在stl中的數(shù)據(jù)個(gè)數(shù)用size表示,而在string是用來表示字符串的所以其表示長度用length,但是為了統(tǒng)一以及不修改源碼(不刪除length)的情況下,string下就既有size()又有l(wèi)ength(),對(duì)此我們建議用size,size在其他容器中也有。size和length的用法是一樣的,就是直接對(duì)象.size() /? 對(duì)象.length()。
- max_size();? 函數(shù)是查看最大長度,但是因?yàn)椴煌幾g器下用的版本不同就導(dǎo)致了其最大長度是不一樣的這個(gè)接口對(duì)于我們的使用無意義基本不用。
- 同樣的capacity()函數(shù)也是在不同編譯器下是不同的,并且增長也會(huì)不同(在vs(PJ)下基本是1.5倍增長,Linux(SGI)下是2倍增長)
- clear( )函數(shù)(清理string中存的數(shù)據(jù)):把size變成0,capacity不變
細(xì)節(jié):
3.1reserve()
![]()
功能:對(duì)string的容量進(jìn)行自行的確定(可以申請(qǐng)空間也能縮小空間),一般應(yīng)用于當(dāng)我們知道需要用到多大的空間處,就能直接一次性的開辟怎么大的空間,避免再每次不夠了再進(jìn)行擴(kuò)容(能一定的提高效率),并且此時(shí)申請(qǐng)的空間會(huì)大于等于所要申請(qǐng)的空間(像vs環(huán)境下就會(huì)多開一段,而centos7下就剛好和申請(qǐng)的空間一樣)
具體如下:
在vs環(huán)境下進(jìn)行開辟空間:
?
在Linux下:
?當(dāng)縮小空間時(shí),是否會(huì)縮小的空間,看的是容器中是否還有數(shù)據(jù),若有則不會(huì)縮小:
?
反之則縮:
?
3.2resize()
功能: 既能去申請(qǐng)空間,并且可以對(duì)申請(qǐng)的空間進(jìn)行初始化(默認(rèn)初始化為\0)
具體如下:
?
也可以指定初始化(也就是第二個(gè)重載函數(shù)的意義):
?
當(dāng)他縮小空間時(shí),他會(huì)先把超過范圍的數(shù)據(jù)不算在內(nèi)用\0隔開(相當(dāng)于后面的數(shù)據(jù)給你刪了):
?
附:綜上所述,對(duì)于縮容情況來說,一般都是不會(huì)進(jìn)行的,除了clear清除數(shù)據(jù)后的reserve縮容才進(jìn)行了縮容,主要原因是縮容的效率是挺低的(它需要去先移動(dòng)縮容后剩下的數(shù)據(jù)到新的空間處再進(jìn)行把原位置的空間進(jìn)行釋放),并且現(xiàn)在的內(nèi)存也挺多的并不會(huì)去怕內(nèi)存不夠這種情況所以就不為了內(nèi)存而降低效率所以一般是不會(huì)縮容的。
3.3strink_to_fit()
功能:一個(gè)主動(dòng)縮小空間的接口,將capacity減到合適的大小,一般把capacity減小到size大小或者比size大一些的值?(但注意他也并不一定會(huì)縮小這是給編譯器一個(gè)建議)
?
4.對(duì)string空間的元素訪問的接口函數(shù)
4.1operator[]
功能:可以直接當(dāng)成數(shù)組一樣的去訪問其string內(nèi)部的元素,在上面已經(jīng)實(shí)現(xiàn)過來就不再過多贅述了
他還可以用來訪問了元素然后進(jìn)行修改,具體如下:
?
當(dāng)越界時(shí)會(huì)報(bào)出斷言錯(cuò)誤,而at()接口(其用法和 [ ] 一樣就不寫了用處也不大,有興趣的可以查一下文檔)則會(huì)報(bào)出異常錯(cuò)誤。
5.修改string的內(nèi)容的接口函數(shù)
5.1assign()
?
功能:進(jìn)行賦值操作,將string內(nèi)原有的值覆蓋掉。
具體如下:
?
但其實(shí)我們平常并不喜歡用? 而是喜歡直接用重載操作符 = ,但他完成一些=運(yùn)算符重載函數(shù)完成不了的賦值方法如:上面的第2、4、5、6 的重載函數(shù),此時(shí)他們有多個(gè)參數(shù)完成(而對(duì)于運(yùn)算符=他只能有兩個(gè)操作數(shù))
5.2insert()
?
功能:在指定pos位置處插入數(shù)據(jù)
具體如下:
?
當(dāng)要注意insert不要多用,其在非尾部插入效率都是比較低的?
5.3erase()
?
功能:對(duì)指定位置處刪除len個(gè)字符(若不寫len則刪除指定位置及其后面的所有字符因?yàn)槿笔?/strong>參數(shù)npos是一個(gè)非常大的值(整形最大值))
具體使用:
?
?
附:replace()是一個(gè)交換函數(shù)接口可以把指定的數(shù)據(jù)改變成想要的數(shù)據(jù),但該函數(shù)接口并不常用,所以就不寫了想了解可以查一下文檔
6.對(duì)字符串操作的一些接口
6.1c_str()
?
功能:該函數(shù)是用來直接指向順序表中的數(shù)組的(string實(shí)際是用一個(gè)順序表來實(shí)現(xiàn)的)
?
?
有了這個(gè)函數(shù)就能去和c的接口函數(shù)合否則是c無法識(shí)別string類型的(因?yàn)橛行〤語言地方他只能和內(nèi)置類型去對(duì)接 (FILE * fopen ( const char * filename, const char * mode );))
6.2find()
?
功能:從pow位置開始往后查找字符串/字符,并且返回第一次出現(xiàn)時(shí)的位置,若沒找到則會(huì)返回npos(整形最大值)
具體使用方法如下:
補(bǔ)充一個(gè)函數(shù)接口:substr()?
?
功能: 他能從指定pos位置開始往后len個(gè)字符的字符串放到string內(nèi)并把這個(gè)string返回。
下面用這個(gè)兩個(gè)函數(shù)來實(shí)現(xiàn)把一個(gè)網(wǎng)址劃分成協(xié)議、域名、資源名(動(dòng)態(tài)版無論什么網(wǎng)址都能進(jìn)行分隔)
?
1 #include<iostream> 2 using namespace std;3 4 int main()5 {6 string s = "https://legacy.cplusplus.com/reference/string/string/find/";7 8 string protocol; 9 10 size_t pos1= s.find("://");11 if(pos1 != s.npos)12 {13 cout << s.substr(0,pos1) << endl;//參數(shù)pos1表示的是個(gè)數(shù)此時(shí)從0位置開始到pos1個(gè)就剛好是協(xié)議名14 }15 16 string domain;17 string uri;18 int pos2 = s.find('/',pos1+3);//可以確定開始的位置 W> 19 if(pos2 != s.npos)20 {21 cout << s.substr(pos1+3,pos2-(pos1+3)) << endl;22 cout << s.substr(pos2+1) << endl;23 }24 return 0;25 }
?
6.3rfind
其功能和find幾乎一樣只是反過來從后面往前找字符/字符串,就不贅述了。
?
6.4 find_first_of 、find_last_of
find_first_of:
功能:是在對(duì)象字符串中從前往后查看是否有參數(shù)中的字符(返回第一次出現(xiàn)的下標(biāo)位置),若果有就返回其下標(biāo)位置,若沒有則返回npos
具體如下:
?
find_last_of :
功能:和 find_first_of 一樣只不過此時(shí)是從后往前找
附還有類似相反的函數(shù):find_first_not_of 以及? find_last_not_of :: 他們是用來查找參數(shù)字符中沒有出現(xiàn)過的返回其下標(biāo)、last同樣只是反過來了從后面往后查找而已,同樣當(dāng)沒有時(shí)就會(huì)返回npos
?
但其實(shí)他們都沒有非常的有用,我們只需要了解一下,有函數(shù)能查找在字符串中出現(xiàn)、查找字符串中沒出現(xiàn)過的字符(在參數(shù)字符串中的會(huì)一 一進(jìn)行查找,當(dāng)出現(xiàn)時(shí)就會(huì)返回第一次出現(xiàn)的字符的下標(biāo))
7.string中的非成員函數(shù)重載
7.1一些常用的運(yùn)算符函數(shù)重載
知識(shí)點(diǎn):
7.1.1比較類運(yùn)算符重載
功能:在String中已經(jīng)重載其比較的重載運(yùn)算符,所以我們就直接使用這些來比較即可能直接當(dāng)成內(nèi)置類型一樣的來使用(不過要注意的是其比較的底層還是重載運(yùn)算符以及是用ASCII碼來對(duì)應(yīng)著比較的)
具體如下:
?
附:雖然string中有compare()比較函數(shù)但是,他并沒用下面的這種方式好用就不去講他了,主要就寫下面這種運(yùn)算符重載的方法。
7.1.2string的 operator +
功能:用法很簡單,因?yàn)閟tring他已經(jīng)幫我們實(shí)現(xiàn)好了,所以只需要去直接用就好,就像內(nèi)置類型的加法一樣,他并不會(huì)改變加的變量,只是用該變量返回加好后的值(此處的加就是加上字符/字符串)。?
具體如下:
?
7.1.3 getline
功能:讀取一行的數(shù)據(jù),遇到\n才會(huì)停止?
在有些編譯器下需要加上頭文件:#include<string>
實(shí)例:一般用于當(dāng)字符串中用空格分隔時(shí),cout 、 printf 他們不能直接讀取字符串時(shí)
具體如下:
?
?
7.2 把字符串與其他類型的相互轉(zhuǎn)換
功能:用來將字符串和其他多種字符進(jìn)行轉(zhuǎn)換的。
stoi把字符串轉(zhuǎn)化成整形,stol :...? 長整形 ...? ?、to_string把某類型轉(zhuǎn)化成字符串
重載函數(shù)如下:
其中to_string很簡單就不講了(看下面的例子就能看懂);那stoi舉例(把字符串轉(zhuǎn)化成整形)其中第一個(gè)參數(shù)是字符串,idx是表示從字符串的那個(gè)下標(biāo)開始往后轉(zhuǎn)換,而base表示的是轉(zhuǎn)換成幾進(jìn)制的整形(后面的兩個(gè)參數(shù)一般是不用管的)。?
具體如下:
?
本章完。預(yù)知后事如何,暫聽下回分解。
如果有任何問題歡迎討論哈!
如果覺得這篇文章對(duì)你有所幫助的話點(diǎn)點(diǎn)贊吧!
持續(xù)更新大量C++細(xì)致內(nèi)容,早關(guān)注不迷路。