目錄
1. string類的優(yōu)勢
2. string類的常用接口
2.1 常用構(gòu)造
1. 空串構(gòu)造:string();
2. C串構(gòu)造:string(const char* s);
3. 拷貝構(gòu)造:string(const string& str);
4. 字符填充構(gòu)造:string(size_t n, char c);
5. 迭代器構(gòu)造:string(InputIterator first, InputIterator last);
2.2 ?string容量操作
1. size_t size(),size_t length()
?2. size_t capacity() const
?3. bool empty() const
?4. void clear()
?5. void reserve(size_t n = 0)
?6. void resize(size_t n),?void resize(size_t char c)
2.3 類對象的訪問
1. char& operator[](size_t pos),const char& operator[](size_t pos) const
?2. begin()、end()
?3. rbegin()、rend()
2.4?string對象處理函數(shù)
1. push_back()
2. append()
?3. operator+=
?4. c_str()
?5. insert()
6. erase()
7. find()、rfind()
8. substr()
9. getline()
1. string類的優(yōu)勢
?????????STL(Standard Template Library)庫中的string類是一個字符串類,它提供了管理字符串的各種方法和功能。它是一個可變長度的字符序列,可以自動調(diào)整自身大小以適應(yīng)字符串的長度變化。
? ? ? ? 在之前我們操作字符串都是通過自己去實現(xiàn)相關(guān)的函數(shù)來進(jìn)行操作,而且稍不留神就會內(nèi)存泄漏,在C++中我們更傾向于使用string類來完成和字符串相關(guān)的操作。
????????使用string類相比于使用C語言的字符串有以下優(yōu)點:
-
更加安全:C語言的字符串沒有自帶長度信息,容易造成內(nèi)存越界等安全問題。而string類包含有字符串長度信息,能夠避免這類問題。
-
更加方便:C語言中處理字符串需要使用一系列函數(shù),如strlen、strcmp、strcat等等,使用起來比較繁瑣。而string類提供了一系列方法,如length、compare、append等等,使用起來更加直觀方便。
-
更加靈活:string類可以動態(tài)地改變字符串的長度,而C語言的字符串長度通常是固定的。
-
更加高效:string類內(nèi)部實現(xiàn)了很多優(yōu)化,如字符串復(fù)制采用了引用計數(shù)和寫時復(fù)制等技術(shù),因此性能相對于C語言的字符串更高。
2. string類的常用接口
2.1 常用構(gòu)造
? ? ? ? C++98中支持7種構(gòu)造函數(shù)?,如下:
- default (1)? string();
- copy(2) string(const string& str);
- substring(3) string(const string& str, size_t pos, size_t len = npos);
- from c - string(4) string(const char* s);
- from sequence(5) string(const char* s, size_t n);
- fill(6) string(size_t n, char c);
- range(7) template <class InputIterator>?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? string(InputIterator first, InputIterator last);
? ? ? ? ?但是我們只對其中的五個進(jìn)行講解:
1. 空串構(gòu)造:string();
? ? ? ? 這個構(gòu)造函數(shù)會構(gòu)造一個空字符串,長度為0個字符,但是容量不一定為零,比如在vs下空string對象的容量是15,不同環(huán)境可能有所不同,主要為了避免頻繁的擴(kuò)容操作。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1; //創(chuàng)建一個空字符串
cout << s1 << endl;
cout << s1.capacity() << endl;
}
?輸出:
2. C串構(gòu)造:string(const char* s);
? ? ? ? 以null結(jié)尾的字符序列(C串)構(gòu)造string對象。
int main()
{
string s1("hello world!");
cout << s1 << endl;
}
輸出:
3. 拷貝構(gòu)造:string(const string& str);
????????利用一個已經(jīng)存在的string對象構(gòu)造對象。
int main()
{
string s1("hello world!");
cout << s1 << endl;
string s2(s1);
cout << s2 << endl;
}
?輸出:
4. 字符填充構(gòu)造:string(size_t n, char c);
? ? ? ? ?利用n個字符構(gòu)造string對象。
int main()
{
string s1(5, 'c');
cout << s1 << endl;
}
輸出:
5. 迭代器構(gòu)造:template <class InputIterator>?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??????????????????????????string(InputIterator first, InputIterator last);
? ? ? ??使用迭代器區(qū)間來構(gòu)造string對象。
int main()
{
string s1(5, 'c');
cout << s1 << endl;
string s2(s1.begin(), s1.end());
cout << s2 << endl;
}
輸出:
2.2 ?string容量操作
1. size_t size(),size_t length()
? ? ? ? size()和length()都是返回字符串的有效字符長度,倆個函數(shù)的實現(xiàn)原理也完全相同,引入size()是為了和其他容器的接口保持一致。
int main()
{
string s1(5, 'c');
cout << s1.length() << endl;
cout << s1.size() << endl;
}
輸出:
?2. size_t capacity() const
? ? ? ? capacity()是返回空間的總大小,在vs下對象的初始容量是15,當(dāng)存儲的對象超過這個大小的時候才會去開空間,在新開的空間存儲數(shù)據(jù)。
int main()
{
string s1(5, 'c');
cout << s1.capacity() << endl;
string s2(16, 'c');
cout << s2.capacity() << endl;
}
輸出:
?3. bool empty() const
? ? ? ? 檢測字符串是否是空串,是返回true,不是返回false。
int main()
{
string s1(5, 'c');
if (s1.empty())
{
cout << "true" << endl;
cout << "空" << endl;
}
else
{
cout << "false" << endl;
cout << "非空" << endl;
}
}
輸出:
?4. void clear()
? ? ? ? 清空對像中的有效字符。
int main()
{
string s1("hello world!");
cout << s1 << endl;
cout << "--------------------------------" << endl;
s1.clear();
cout << s1 << endl;
}
輸出:
?5. void reserve(size_t n = 0)
? ? ? ? reserve()是為了給對象預(yù)留空間,如果我們提前得知字符串需要的空間我們就可以提前開好,避免頻繁擴(kuò)容帶來的性能消耗。當(dāng)reserve的參數(shù)小于string底層空間大小的時候,reserve就不會對容量進(jìn)行處理。(一般為了保障程序的安全性,reserve()會多開出一部分空間)。
int main()
{
string s1(10,'x');
s1.reserve(20);
cout << s1.capacity() << endl;
s1.reserve(2);
cout << s1.capacity() << endl;
}
輸出:
?6. void resize(size_t n),?void resize(size_t char c)
? ? ? ? 修改字符有效個數(shù)為n,多出的空間用字符c填充。如果n小于有效字符數(shù),本質(zhì)就是刪字符操作。如果容量不夠會擴(kuò)容。
int main()
{
string s1(10, 'x');
cout << s1 << endl;
s1.resize(20, 'c');
cout << s1 << endl;
s1.resize(2);
cout << s1 << endl;
}
輸出:
2.3 類對象的訪問
1. char& operator[](size_t pos),const char& operator[](size_t pos) const
? ? ? ? 返回pos位的字符,并且可以對非const對象進(jìn)行修改。
int main()
{
string s1(10, '1');
cout << s1 << endl;
s1[4] = '0';
cout << s1 << endl;
for (int i = 0; i < 10; i++)
{
cout << s1[i] << ' ';
}
}
輸出:
?2. begin()、end()
? ? ? ? begin()返回第一個字符位置的迭代器,end()返回最后一個字符的下一個位置的迭代器。begin()和end()都返回了自己的const版本。
int main()
{
string s1(10, '1');
auto it = s1.begin();
for (; it < s1.end(); it++)
{
cout << *it;
}
}
輸出:
?3. rbegin()、rend()
? ? ? ? rbegin()獲取一個反向迭代器,指向其反向開頭,rend()獲取一個反向迭代器,指向其反向結(jié)尾的前一個理論元素。
int main()
{
string s1("123456789");
cout << s1 << endl;
auto it = s1.rbegin();
for (; it < s1.rend(); it++)
{
cout << *it;
}
}
輸出:
2.4?string對象處理函數(shù)
1. push_back()
? ? ? ? 在字符串后尾插字符c。
int main()
{
string s1;
s1.push_back('1');
cout << s1;
}
輸出:
2. append()
? ? ? ? append()函數(shù)在在C++98有六種重載形式,用于在字符串后追加一個字符串。
- string(1)? ? ? ?string& append(const string& str);
- substring(2) string& append(const string& str, size_t subpos, size_t sublen);
- c - string(3)? string & append(const char* s);
- buffer(4)? ? ? ?string& append(const char* s, size_t n);
- fill(5)? ? ? ? ? ? ?string& append(size_t n, char c);
- range(6)? ? ? ?template <class InputIterator>? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?string& append(InputIterator first, InputIterator last);
int main()
{
string s1("hello");
string s2(" world");
cout << s1 << endl;
s1.append(s2); //在s1結(jié)尾追加一個s1
cout << s1 << endl;
s1.append(s2, 1, 2); //在s1結(jié)尾追加s1的下標(biāo)為1往后的倆個字符
cout << s1 << endl;
s1.append("C串"); //在s1后追加一個C串
cout << s1 << endl;
s1.append("123456", 2);//在s1后追加字符串的前 n 個字符。
cout << s1 << endl;
s1.append(5, 'c'); //在s1后追加5個字符‘c’
cout << s1 << endl;
string s3("CSDN");
s1.append(s3.begin(), s3.end());//在s1后追加一個迭代器區(qū)間
cout << s1 << endl;
}
?輸出:
?3. operator+=
? ? ? ? operator+=()和append()功能類似,都是在字符串后追加內(nèi)容,但是我們在實際開發(fā)中更愿意使用operator+=。
int main()
{
string s1("hello ");
string s2("world!");
s1 += s2;
cout << s1 << endl;
}
輸出:
?4. c_str()
? ? ? ? c_str()會返回string對象存儲字符串的首地址,用戶可以通過這個接口來適配c語言中的某些場景。
int main()
{
string s1("hello world!");
printf("%s", s1.c_str());
}
輸出:
?5. insert()
? ? ? ? insert()支持在pos位對字符串進(jìn)行插入操作,但是由于pos位插入涉及到元素的挪動,而挪動元素會使性能下降,所以insert()要少用。insert()有多種重載形式,如下:
- string(1)? ? ? ?string& insert(size_t pos, const string& str);
- substring(2) string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);
- c - string(3)? string & insert(size_t pos, const char* s);
- buffer(4)? ? ? ?string& insert(size_t pos, const char* s, size_t n);
- fill(5)? ? ? ? ? ? ?string& insert(size_t pos, size_t n, char c);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void insert(iterator p, size_t n, char c);
- single character(6) iterator insert(iterator p, char c);
- range(7)? ? ? ? template <class InputIterator>? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void insert(iterator p, InputIterator first, InputIterator last);
int main()
{
string s1("string");
cout << s1 << endl;
s1.insert(2, "*********");
cout << s1 << endl;
}
輸出:
6. erase()
? ? ? ? erase()是刪除字符串的一部分,但是不會改變string對象的容量,如果給的刪除字符個數(shù)大于pos位后的字符個數(shù),會將后面的全部刪除。如果沒有給pos位,則默認(rèn)清空字符串。如果不給刪除個數(shù)則默認(rèn)是無符號整型npos(-1)即約等于42億,就會將pos位后面的字符序列全部刪除。
- sequence(1) string& erase(size_t pos = 0, size_t len = npos);
- character(2) iterator erase(iterator p);
- range(3)? ? ? ?iterator erase(iterator first, iterator last);
int main()
{
string s1("1234567890");
s1.erase(2, 3);//從pos位2開始依次刪除三個字符,即刪除"345"
cout << s1 << endl;
s1.erase(s1.begin() + 5);
cout << s1 << endl;//刪除迭代器位置的字符
s1.erase(s1.begin(), s1.begin() + 2);//刪除beigin()位置和后面1位字符
cout << s1 << endl;
}
?輸出:
7. find()、rfind()
? ? ? ? find()函數(shù)用于查找某字符串中是否包含某個字符或者字符串,會從pos位往后查找,rfind()則是從pos位往前查找。找到后會返回字符首次出現(xiàn)的pos位或者字符串首次出現(xiàn)的pos位。如果沒有找到則會返回npos(無符號整型‘-1’)。
- string(1)? ? ? ?size_t find(const string& str, size_t pos = 0) const;
- c - string(2)? size_t find(const char* s, size_t pos = 0) const;
- buffer(3)? ? ? ?size_t find(const char* s, size_t pos, size_t n) const;
- character(4) size_t find(char c, size_t pos = 0) const;
int main()
{
string s1("hello world");
size_t pos = s1.find("llo", 0);
cout << pos << endl;
}
輸出:
8. substr()
? ? ? ? substr()會獲取pos后包括pos位的n個字符并且返回一個string對象,如果沒有給獲取長度n,則會默認(rèn)將后面的包括pos位的所有字符全部獲取并且返回一個string對象。
- string substr(size_t pos = 0, size_t len = npos) const;
int main()
{
string s1("123456789");
cout << s1 << endl;
string s2(s1.substr(2, 5));
cout << s2 << endl;
}
?輸出:
9. getline()
?????????從 istream 中提取字符并將其存儲到 str 中,直到找到分隔字符 delim(或 (2) 的換行符“\n”)。如果在 is 中到達(dá)文件末尾或在輸入操作期間發(fā)生其他錯誤,則提取也會停止。如果找到分隔符,則將其提取并丟棄(即不存儲它,下一個輸入操作將在它之后開始)。請注意,調(diào)用之前的任何內(nèi)容都將替換為新提取的序列。每個提取的字符都追加到字符串中,就像調(diào)用其成員push_back一樣。(不以空格作為分隔符,可以讀取空格符)文章來源:http://www.zghlxwxcb.cn/news/detail-675549.html
- (1)istream& getline(istream& is, string& str, char delim);
- (2)istream& getline(istream& is, string& str);
?文章來源地址http://www.zghlxwxcb.cn/news/detail-675549.html
到了這里,關(guān)于【C++精華鋪】9.STL string的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!