目錄
一,STL
1. 簡介
2. STL的版本
3. STL 六大組件??
4.? 學習STL, 三境界
5. 學會查看C++文檔?
二, string類
1. 相對于C語言,我們?yōu)槭裁催€需要學習C++的string?
2. 頭文件
3.? 常見構(gòu)造函數(shù)
4.? operator=???
5.? operator[]? &&? at函數(shù)
6. string容量方面
1. 關(guān)于? size 與 length? 的選擇
2. 關(guān)于string類?的擴容機制
3.? 設(shè)置容量
7. iterators——迭代器(重要)
1. 回望 C++入門的 范圍 for (語法糖? for)
2. 反向迭代
8. 字符串插入
1. 常見的插入方式:
2. 關(guān)于中間插入 insert的使用?
9. 刪除字符串——erase
10.? c_str
1. 使用場景
?2. ‘\0’在 C語言? &? C++string類中的區(qū)別
11. find & rfind
1.獲取文件名后綴
?2. 分離網(wǎng)址
12. getline
13. 字符串 互相轉(zhuǎn)化? 其他數(shù)據(jù)(C++11)
關(guān)于string類使用總結(jié)
結(jié)語
一,STL
1. 簡介
STL(standard template libaray-標準模板庫):是C++標準庫的重要組成部分,不僅是一個可復(fù)用的組件庫,而且是一個包羅數(shù)據(jù)結(jié)構(gòu)與算法的軟件框架。
2. STL的版本
3. STL 六大組件??
4.? 學習STL, 三境界
1. 熟練使用 STL。
2. 能夠比較清晰的認識STL的底層原理。
3. 能夠編寫STL的擴展。(在校期間,少數(shù)能掌握)
5. 學會查看C++文檔?
??Reference - C++ Reference (cplusplus.com)
學習中光string類就有100來個接口,我們熟練掌握常見20個,其余80來個需要我們查找文檔,而最好的方式是查看英文原文檔。?
二, string類
1. 相對于C語言,我們?yōu)槭裁催€需要學習C++的string?
2. 頭文件
?在使用string類時,必須包含頭文件以及using namespace std;
#include <string>
3.? 常見構(gòu)造函數(shù)
?常見的string類構(gòu)造函數(shù)及功能:
這是原文:
選擇 constructor (函數(shù))進入:?
即可見?
建議:嘗試去閱讀原文檔,對函數(shù)功能的解釋。

演示如下:
int main()
{
// string(const char* s) (重點) 用string來構(gòu)造string類對象
string s1("hello, C++");
cout << "s1 :" << s1 << endl;
// string() (重點) 構(gòu)造空的string類對象,即空字符串
string s2;
cout << "s2 :" << s2;
cin >> s2;
cout << "s2 :" << s2 << endl;
// string(const string & s) (重點) 拷貝構(gòu)造函數(shù)
string s3(s1);
cout << "s3 :" << s3 << endl;
// string(size_t n, char c) string類對象中包含n個字符c
string s4(4, 'c');
cout << "s4 :" << s4 << endl;
return 0;
}
這里單獨對第三個函數(shù) 子鏈函數(shù)? 進行解釋:
4.? operator=???
?成員函數(shù):
?功能展示:
int main()
{
string s2;
// string & operator= (const char* s);
string s1 = "hello, C++"; // 構(gòu)造 + 拷貝 -> 優(yōu)化為一次構(gòu)造
cout << "s1: " << s1 << endl; // 結(jié)果: hello, C++
// string& operator= (const string & str);
s2 = s1;
cout << "s2: " << s2 << endl; // 結(jié)果: hello, C++
// string& operator= (char c);
s2 = 'x';
cout << "s2: " << s2 << endl; // 結(jié)果: x
return 0;
}
補充: assign 函數(shù) 跟賦值差不多,感興趣可以去查查文檔,這里不進行舉出。
5.? operator[]? &&? at函數(shù)
功能描述: 兩者都是使string類像數(shù)組一樣的訪問字符串。
成員函數(shù):
?
區(qū)別在返回值?
operator[]? 在越界時會發(fā)生 斷言?;at 訪問越界則 返回 異常。
功能展示:?
int main()
{
// 1. char& operator[] (size_t pos); // 返回可修改的別名
string s1 = "hello, C++";
cout << s1[4] << endl; // at : s1.at(4)
s1[4] = 'k'; // 如果類對象實例化時,未被const修飾,同時也具有修改的能力
// 2. const char& operator[] (size_t pos) const;
const string s2 = s1;
cout << s2[4] << endl;
s2[4] = 'o'; // s2 被const修飾,不允許修改其內(nèi)容
return 0;
}
?6. string容量方面
1. 關(guān)于? size 與 length? 的選擇
兩者功能都是獲取容器中字符串長度
?一般推薦使用 size() ,因為 length出道比較早,size是后期出道,string類中使用 size 比較多。(注意: max_size 這個沒什么意義,返回的都是41億)
簡單遍歷輸出一遍字符串:
int main()
{
string s1 = "hello, C++";
for (int i = 0; i < s1.size() ; i++)
{
cout << s1[i]; // at: s1.at(i);
}
return 0;
}
2. 關(guān)于string類?的擴容機制
結(jié)論: 在不同編譯器下擴容機制可能不同,有的是1.5倍,而有的是2倍的擴容。(STL標準庫,只是一種標準,不同的編譯器廠商有著自己的功能實現(xiàn)方法)
這里用同一段代碼在 linux g++和 VS2019 下 擴容的結(jié)果:
?
3.? 設(shè)置容量
我們知道頻繁擴容,會有額外的消耗,于是我們預(yù)先設(shè)定一定大小的容量,減少擴容次數(shù)。
函數(shù):
簡單使用:
s1.reserve(1000); // 單純開空間
s2.resize(1000); // 開空間, 同時設(shè)置字符,默認為‘0’
s2.resize(1000, 'c');
7. iterators——迭代器(重要)
迭代器是string 中的內(nèi)部類類型,功能跟 operator[]差不多,像數(shù)組一樣的訪問數(shù)據(jù)。但字符串底層是數(shù)組,是一段連續(xù)的空間,用operator[] 會比較便利。后面我們學習 STL的vector(順序表), list(鏈表)后,我們會發(fā)現(xiàn),operator[]在連續(xù)存儲的數(shù)據(jù)結(jié)構(gòu)訪問還行,但鏈表,樹,迭代器更合適,而且他們用法類似,因此我們同時學習迭代器。(迭代器是容器通用訪問方式,用法類似,提前上路)
簡單用法:
int main()
{
string s1 = "hello, C++";
string::iterator it = s1.begin();
while (it != s1.end()) // != 原因:1. string類本身有關(guān) 2.其他容器也是用 != 這樣設(shè)計統(tǒng)一了
{
cout << *it;
it++;
}
return 0;
}
s1.begin() 和? s1.end() 返回迭代器的位置是? ?[左閉區(qū)間 右開區(qū)間)??
1. 回望 C++入門的 范圍 for (語法糖? for)
int main()
{
string s1 = "hello, C++";
for ( auto e : s1) // 自動++, 自動判斷結(jié)束
{
cout << e;
}
return 0;
}
語法糖? 底層是通過 迭代器實現(xiàn),且只能正向遍歷。
2. 反向迭代
功能:反向遍歷數(shù)據(jù)
?簡單用法:
int main()
{
string s1 = "hello, C++";
string::reverse_iterator it = s1.rbegin();
while ( it != s1.rend())
{
cout << *it;
it++; // 底層肯定是反向++
}
return 0;
}
當然 不管是 s1.begin ,s1.end; s1.rbegin, s2.rend都有返回 const 修飾的迭代器重載函數(shù)(一般發(fā)生在 傳string引用時,如: const string& s1)
8. 字符串插入
C語言中,庫函數(shù)strcat 也有這樣的功能,但沒有C++這么智能,C語言劣勢:
- 1. 每次插入字符,字符串需要遍歷整個字符串,效率低,且需要保證被插入的字符數(shù)組足夠大。
- 2. C++的插入會記錄末尾字符下標,可以做到直接插入。
1. 常見的插入方式:
1. push_back
2. append
3. operator +=?
詳細查文檔
簡答操作:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello, C++");
s1.push_back('6');
s1.push_back('-');
s1.push_back('-');
cout << s1 << endl;
s1.append("5");
cout << s1 << endl;
string s2(s1);
s2 += s1;
s2 += 'c';
s2 += "你好";
cout << s2 << endl;
return 0;
}
2. 關(guān)于中間插入 insert的使用?
結(jié)論: 盡量少用,string類,insert 中間插入,會導致后面字符挪位,假設(shè)要頭插入n個字符,第2次,挪一次; 第3次,挪2次;第n次,挪 n - 1次;所以挪位時間復(fù)雜度為n2了,所以盡量少用。
常見的三個insert 的使用:
運用如下:
int main()
{
// 1. 迭代器
string s1 = "hello, C++";
string::iterator it = s1.begin() + 2; // 也就是在下標為2的位置插入
s1.insert(it, 'Z');
cout << s1 << endl; // heZllo, C++
string s2 = s1;
s2.insert(2, "你好"); // 下標為2的位置
cout << s2 << endl;
string s3 = s1;
s3.insert(5, s2); // 下標為5的位置插入
cout << s3 << endl;
return 0;
}
9. 刪除字符串——erase
?函數(shù): erase
代碼實踐:?
int main()
{
// 1. 迭代器
string s1 = "hello, C++";
string::iterator it = s1.begin() + 2; // 也就是在下標為2的位置插入
s1.insert(it, 'Z');
cout << s1 << endl; // heZllo, C++
string s2 = s1;
s2.insert(2, "你好"); // 下標為2的位置
cout << s2 << endl;
string s3 = s1;
s3.insert(5, s2); // 下標為5的位置插入
cout << s3 << endl;
// 1. 迭代器刪除
//s3.erase(2);
string::iterator it2 = s3.begin() + 2;
string::iterator it3 = s3.end();
s3.erase(it2, it3);
cout << s3 << endl;
return 0;
}
10.? c_str
1. 使用場景
在一些需要用到C語言接口時,C語言不支持C++的string類,而c_str 成員函數(shù)可以將string類字符串轉(zhuǎn)化為C語言兼容的字符串。
如:用C語言訪問文件夾
string s1("Test.cpp");
const char* file = s1.c_str();
FILE* myfile = fopen( file, "r"); // 不認string類
char i = fgetc(myfile);
while ( i != EOF)
{
cout << i;
i = fgetc(myfile);
}
?2. ‘\0’在 C語言? &? C++string類中的區(qū)別
結(jié)論:?
C語言比較重要:? ‘\0’在C語言中,像strcopy, strcat等等字符串接口函數(shù)結(jié)束大多有 '\0' 作為字符串結(jié)尾;
C++直接無視: 我們可以將字符串中間任意位置設(shè)置為\0,但是在C++中字符串會將\0當成一個正常字符處理(打印時會當成空格或者不占位置的字符輸出)
int main()
{
string s1("test.cpp");
s1 += '\0';
s1 += '\0';
s1 += '\0';
s1 += '\0';
s1 += "test.cpp";
cout << s1.c_str() << endl; // ‘\0’對于C語言,是字符串結(jié)束的標志
cout << s1 << endl; // 而在string中,字符串中可以存在,但不發(fā)生顯示或者是空格。
return 0;
}
11. find & rfind
pos: 開始查找的字符位
n:? ?匹配的字符序列的長度
1.獲取文件名后綴
int main()
{ // 1. 簡單文件獲取后綴
string s1("test.cpp");
size_t i = s1.find('.');
string tmp;
if (i != string::npos)
{
tmp = s1.substr(i); // 先用獲取子串函數(shù)
}
cout << tmp << endl;
// 2. 復(fù)雜后綴,而只取最后的后綴
string s2("test.cpp.tar.zip");
size_t i2 = s2.rfind('.'); // 從后向前尋找
string tmp2;
if (i2 != string::npos)
{
tmp2 = s2.substr(i2);
}
cout << tmp2;
return 0;
}
?補充一下substr:
?2. 分離網(wǎng)址
int main()
{
string s1("https://mp.csdn.net/mp_blog/creation/editor/131103529");
// 1. 協(xié)議
size_t pl = s1.find("://");
size_t next = pl;
string protocol = s1.substr(0, pl);
cout << protocol << endl;
// 2. 域名
size_t p2 = s1.find("/", next += 3);
string rn = s1.substr(next, p2 - next);
next = p2;
cout << rn << endl;
// 3. 資源名
string way = s1.substr(next);
cout << way << endl;
return 0;
}
12. getline
?功能:用于從輸入流中讀取一行數(shù)據(jù),并存儲到string對象中。
is:輸入流對象。
str:用于存儲讀取的數(shù)據(jù)的string對象。
delim:可選參數(shù),表示行結(jié)束符,默認為'\n'。(沒有空格作為結(jié)束符)
?比如??瓦@道題:
字符串最后一個單詞的長度_牛客題霸_??途W(wǎng) (nowcoder.com)
13. 字符串 互相轉(zhuǎn)化? 其他數(shù)據(jù)(C++11)
這個感興趣可以一個個試。舉一個栗子:
stoul :? 字符串? 轉(zhuǎn)? 無符號長整型?
關(guān)于string類使用總結(jié)
? ?1. 學會查文檔!!?。?span style="color:#fe2c24;">重要)
? ?2. 可以問chatgpt
? ?3. 多練則會文章來源:http://www.zghlxwxcb.cn/news/detail-492814.html
結(jié)語
本小節(jié)就到這里了,感謝小伙伴的瀏覽,如果有什么建議,歡迎在評論區(qū)評論;如果給小伙伴帶來一些收獲請留下你的小贊,你的點贊和關(guān)注將會成為博主創(chuàng)作的動力。文章來源地址http://www.zghlxwxcb.cn/news/detail-492814.html
到了這里,關(guān)于【STL】 string類使用一站式攻略的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!