目錄
一.string類
1.1為什么學習string類?
1.2.標準庫中的string類
二.string對象的元素訪問
?2.1.1使用operator[]與at實現訪問
2.1.2正向迭代器訪問
2.1.3反向迭代器訪問
2.1.4const正向迭代器(不能修改)
2.1.5const反向迭代器(不能修改)
2.1.6范圍for
三.string類對象的常見構造
三.?string類對象的容量操作
四.?string類對象的修改操作
?find
五.string類非成員函數
六.將string對象int互相轉換
6.1stoi 將string里第一次遇到的數字字符轉換成int
6.2, to_string 將數字轉化成string對象
七.vs和g++下string結構的說明
7.1vs下string的結構
7.2g++下string的結構
一.string類
1.1為什么學習string類?
1.2.標準庫中的string類
string類的文檔介紹
1. 字符串是表示字符序列的類2. 標準的字符串類提供了對此類對象的支持,其接口類似于標準字符容器的接口,但添加了專門用于操作單字節字符字符串的設計特性。3. string 類是使用 char( 即作為它的字符類型,使用它的默認 char_traits 和分配器類型 ( 關于模板的更多信 息,請參閱basic_string) 。4. string類是basic_string模板類的一個實例,它使用char來實例化basic_string模板類,并用char_traits 和allocator作為basic_string的默認參數(根于更多的模板信息請參考basic_string)。5. 注意,這個類獨立于所使用的編碼來處理字節 : 如果用來處理多字節或變長字符 ( 如 UTF-8) 的序列,這個 類的所有成員( 如長度或大小 ) 以及它的迭代器,將仍然按照字節 ( 而不是實際編碼的字符 ) 來操作。
1. string 是表示字符串的字符串類2. 該類的接口與常規容器的接口基本相同,再添加了一些專門用來操作 string 的常規操作。3. string 在底層實際是: basic_string 模板類的別名, typedef basic_string<char, char_traits, allocator> string;4. 不能操作多字節或者變長字符的序列。 在 使用string類時,必須包含#include頭文件以及using namespace std;
二.string對象的元素訪問
?2.1.1使用operator[]與at實現訪問
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello");//構造for (size_t i = 0; i < s.size(); i++)//讀{cout << s[i] << " ";}cout << endl;for (size_t i = 0; i < s.size(); i++){cout << s.at(i) << " ";}cout << endl;for (size_t i = 0; i < s.size(); i++)//寫,at同理{cout << s[i]+=1 << " ";}}
operator[]與at的區別:
operator[]在元素越界訪問時,采用斷言,at采用拋出異常
2.1.2正向迭代器訪問
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::iterator it = s.begin();while (it != s.end())//讀{cout << *it << " ";it++;}cout << endl;it = s.begin();while (it != s.end())//寫{*it += 1;cout << *it << " ";}cout << endl;return 0;
}
2.1.3反向迭代器訪問
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::reverse_iterator it = s.rbegin();while (it != s.rend())//讀{cout << *it << " ";it++;}cout << endl;it = s.rbegin();while (it != s.rend())//寫{*it += 1;cout << *it << " ";}cout << endl;return 0;
}
2.1.4const正向迭代器(不能修改)
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::const_iterator it = s.begin();while (it != s.end())//讀{cout << *it << " ";it++;}cout << endl;return 0;
}
2.1.5const反向迭代器(不能修改)
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");string::const_reverse_iterator it = s.rbegin();while (it != s.rend())//讀{cout << *it << " ";it++;}cout << endl;return 0;
}
2.1.6范圍for
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");for(auto ch:s)//無法修改{cout<<ch<<" ";}for(auto& ch:s)//可以修改{ch+=1;cout<<ch<<" ";}return 0;
}
三.string類對象的常見構造
string()? ?重點 | 無參構造函數 |
string(const char* s)? 重點 | 用字符串構造對象 |
string(size_t n,char c)? 重點 | 用n個字符構造對象 |
string(const string& s) 重點 | 拷貝構造 |
string(const string& str,size_t pos,size_t len=npos) | 用str從下標(包括)之后len長度的內容,構造對象 |
string(const char* s,size_t n) | 用字符串前n個構造對象 |
template <class InputIterator first,InputIterator last> string(InputIterator first,InputIterator last) | 迭代器區間構造對象 |
注:第四個構造方法,中的npos,是string類中的一個被static修是的,類型為size_t(無符號整形),值為-1

#include<iostream>
#include<string>
using namespace std;int main()
{string s1;//無參構造string s2("abcdefg");//用字符串構造對象string s3(5, 's');//string類對象中包含n個字符string s4(s2);//拷貝構造string s5(s2, 0, 3);//用str從下標(包括)之后len長度的內容,構造對象string s6("abcdefg", 3);//用字符串前n個構造對象string s7(s6.begin(), s6.end());//迭代器區間構造對象cout << "s1=" << s1 << endl;cout << "s2=" << s2 << endl;cout << "s3=" << s3 << endl;cout << "s4=" << s4 << endl;cout << "s5=" << s5 << endl;cout << "s6=" << s6 << endl;cout << "s7=" << s7 << endl;return 0;
}
三.?string類對象的容量操作
size (重點) | 返回字串有效字符長度 |
length | 返回字符串有效長度 |
capacity?? | 返回空間總大小 |
empty (重點) | 檢測字符串是否為空串,是返回true,否則返回false |
clear (重點) | 清空有效字符 |
reserve (重點) | 為字符串預留空間 |
resize (重點) | 將有效字符個數改成n個,多出的空間用字符c填充 |
1.reverse(修改總容量)
#include<iostream>
#include<string>
using namespace std;int main()
{string s("hello C++");cout << s.size() << " " << s.capacity() << endl;s.reserve(100);cout << s.size() << " " << s.capacity() << endl;s.reserve(10);cout << s.size() << " " << s.capacity() << endl;return 0;
}
reserve用于預開空間,如果開辟的空間小于原空間,并不會改變容量
#include<iostream>
#include<string>
using namespace std;int main()
{//resize(n)// resize(size_t n,char x)//分三種情況//1. n<size//2. n>size && n<=capacity//3. n>capacitystring s("hello world");s.resize(10);//cout << s.size() << " " << s.capacity() << " " << s<<endl;s.resize(17);//將size改為17,多出來的用'\0'填充cout << s.size() << " " << s.capacity() << " " << s<<endl;s.resize(40, 'x');//將size改為40,多出來的位置用'x'填充cout << s.size() << " " << s.capacity() << " " << s<<endl;return 0;
}
resize用于調整size,當n大于容量是,會擴容,并用對于的字符填充。
當n>size && n< 容量時,用對應的字符填充多出來的
當n<size 時,會縮容放棄超過的空間。
1. size() 與 length() 方法底層實現原理完全相同,引入 size() 的原因是為了與其他容器的接口保持一致,一般情況下基本都是用 size() 。2. clear() 只是將 string 中有效字符清空,不改變底層空間大小。3. resize(size_t n) 與 resize(size_t n, char c) 都是將字符串中有效字符個數改變到 n 個,不同的是當字 符個數增多時:resize(n) 用 0 來填充多出的元素空間, resize(size_t n, char c) 用字符 c 來填充多出的 元素空間。注意:resize 在改變元素個數時,如果是將元素個數增多,可能會改變底層容量的大 小,如果是將元素個數減少,底層空間總大小不變。4. reserve(size_t res_arg=0) :為 string 預留空間,不改變有效元素個數,當 reserve 的參數小于 string的底層空間總大小時, reserver 不會改變容量大小。
四.?string類對象的修改操作
push_back | 在字符串后尾插字符c |
append | 在字符串后追加一個字符串 |
operator+= ( 重點) | 在字符串后追加字符串 str |
c_str ( 重點 ) | 返回 C 格式字符串 |
find + npos ( 重點 ) | 從字符串 pos 位置開始往后找字符 c ,返回該字符在字符串中的位置 |
rfind | 從字符串 pos 位置開始往前找字符 c ,返回該字符在字符串中的位置 |
substr | 在 str 中從 pos 位置開始,截取 n 個字符,然后將其返回 |
?find
//從pos位置開始找,str
size_t find (const string& str, size_t pos = 0) const noexcept;//從pos位置開始找字符串第一次出現的下標,若不存在返回npos
size_t find (const char* s, size_t pos = 0) const;//從pos位置找字符串s的前n個第一次出現的下標,不存在返回npos
size_t find (const char* s, size_t pos, size_type n) const;size_t find (char c, size_t pos = 0) const noexcept;
通常finf與substr配合使用對找一個網址對應的協議,域名,地址
#include<iostream>
#include<string>
using namespace std;int main()
{
//string s3("https://legacy.cplusplus.com/reference/string/string/rfind/");string s3("ftp://www.baidu.com/?tn=65081411_1_oem_dg");// 協議// 域名// 資源名string sub1, sub2, sub3;size_t i1 = s3.find(':');if (i1 != string::npos)sub1 = s3.substr(0, i1);//查找協議elsecout << "沒有找到i1" << endl;size_t i2 = s3.find('/', i1+3);if (i2 != string::npos)sub2 = s3.substr(i1+3, i2-(i1+3));//查找域名elsecout << "沒有找到i2" << endl;sub3 = s3.substr(i2 + 1);//查找地址cout << sub1 << endl;cout << sub2 << endl;cout << sub3 << endl;
}
五.string類非成員函數
operator+ ? | 盡量少用,因為傳值返回,導致深拷貝效率低 |
operator>> (重點) | 輸入運算符重載 |
operator<< (重點) | 輸出運算符重載 |
getline (重點) | 獲取一行字符串 |
istream& getline(istream& in, string&str, char delim);//從流提取中提取字符串到str中,直到delim或'\n'istream& getline(istream& in,string& str, char);//從流提取中取字符串到str
六.將string對象int互相轉換
6.1stoi 將string里第一次遇到的數字字符轉換成int


6.2, to_string 將數字轉化成string對象

七.vs和g++下string結構的說明
7.1vs下string的結構
當字符串長度小于 16 時,使用內部固定的字符數組來存放當字符串長度大于等于 16 時,從堆上開辟空間
union _Bxty
{ // storage for small buffer or pointer to larger onevalue_type _Buf[_BUF_SIZE];pointer _Ptr;char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

7.2g++下string的結構 ???????
空間總大小字符串有效長度引用計數
struct _Rep_base
{size_type _M_length;size_type _M_capacity;_Atomic_word _M_refcount;
};