String 类和 STL (Standard Template Library)
-
一. string 類
- 1. 構造字符串
- 2. string類輸入
- 3. 使用字符串
- 4. 其他string類方法
- 5. 字符串種類
一. string 類
-
? ? ? ?很多應用程序都需要處理字符串。C語言在string.h(在++中為cstring)中提供了一系列的字符串函數,很多早期的C++實現為處理字符串提供了自己的類。
-
? ? ? ? string類是由頭文件string支持的(以頭文件string.h和cstring支持對C風格字符串進行操縱的C庫字符串函數,但不支持string類)。要使用類,關鍵在于知道它的公有接口,而string類包含大量的方法,其中包括了若干構造函數,用于將字符串賦給變量、合并字符串、比較字符串和訪問各個元素的重載運算符以及用于在字符串中查找字符和子字符串的工具等。以string類包含的內容很多。
1. 構造字符串
-
? ? ? ?先來看string的構造函數。畢竟,對于類而言,最重要的內容之一是,有哪些方法可用于創建其對象。程序清單1使用了string的7個構造函數(用ctor標識,這是傳統C++中構造函數的縮寫)。表1簡要地描述了這些構造函數,它首先按順序簡要描述了程序清單1使用的7個構造函數,然后列出了C++11新增的兩個構造函數。使用構造函數時都進行了簡化,即隱藏了這樣一個事實:string實際上是模板具體化basic_string<char>的一個typedef,同時省略了與內存管理相關的參數。 size_type是一個依賴于實現的整型,是在頭文件string中定義的。string類將string::npos定義為字符串的最大長度,通常為unsigned int的最大值。以表格中使用縮寫NBTS(null終止string)來表示以空字符結束的字符串一一傳統的C字符串。
表1 string類的構造函數
程序清單1 :構 造 函 數
描述
string(const char * s)
將string對象初始化為s指向的NBTS
string(size_type n, char c)
創建一個包含n個元素的string對象,其中每個元素都被初始化為字符c
string(const string & str)
將一個string對象初始化為string對象str(復制構造函數)
string()
創建一個默認的string對象,長度為0(默認構造函數)
string(const char * s, size_type n)
將string對象初始化為s指向的NBTS的前n個字符,即使超過了NBTS結尾
template<class Iter>
string(Iter begin, Iter end)將string對象初始化為區間[begin, end)內的字符,其中begin和end的行為就像指針,用于指定位置,范圍包括begin在內,但不包括end
string(const string & str, size_type pos, size_type n = npos)
將一個string對象初始化為對象str中從位置pos開始到結尾的字符,或從位置pos開始的n個字符
string(string && str) noexcept
這是C++11新增的,它將一個string對象初始化為string對象str,并可能修改str(移動構造函數)
string(initializer_list<char> il)
這是C++11新增的,它將一個string對象初始化為初始化列表il中的字符
#include <iostream> #include <string> // using string constructors int main() { using namespace std; string one("Lottery Winner!"); // ctor #1 cout << one << endl; // overloaded << string two(20, '$'); // ctor #2 cout << two << endl; string three(one); // ctor #3 cout << three << endl; one += " Oops!"; // overloaded += cout << one << endl; two = "Sorry! That was "; //will Clean up the original string in object two three[0] = 'P'; string four; // ctor #4 four = two + three; // overloaded +, = cout << four << endl; char alls[] = "All's well that ends well"; string five(alls,20); // ctor #5 cout << five << "!\n"; string six(alls+6, alls + 10); // ctor #6 cout << six << ", "; string seven(&five[6], &five[10]); // ctor #6 again cout << seven << "...\n"; cout << "Now four is :" << four << endl; string eight(four, 7, 16); // ctor #7 cout << eight << " in motion!" << endl; system("pause"); return 0; }程序清單1 的輸出:
Lottery Winner! $$$$$$$$$$$$$$$$$$$$ Lottery Winner! Lottery Winner! Oops! Sorry! That was Pottery Winner! All's well that ends! well, well... Now four is :Sorry! That was Pottery Winner! That was Pottery in motion! Press any key to continue . . .
2. string類輸入
-
有哪些輸入方式可用呢? 對于C風格的字符串, 有3種方式:
char info[100]; cin >> info; // read a word cin.getline(info, 100); // read a line, discard \n cin.get(info, 100); // read a line, leave \n in queue -
對于string 對象 有兩種方式:
string stuff; cin >> stuff; // read a word getline(cin, stuff); // read a line, discard \n -
兩個版本的getline() 都有一個可選參數, 用于指定使用什么字符作為讀取的邊界;
cin.getline(info,100,':'); // read up to :, discard : getline(cin,stuff, ':'); // read up to :, discard :對于string版本的getline() 能夠自動調整目標string 對象的大小, 使之剛好能存儲輸入的字符:
char fname[10]; string lname; cin >> fname; // could be a problem if input size > 9 characters cin >> lname; // can read a very, very long word cin.getline(fname, 10); // may truncate input getline(cin, fname); // no truncation自動調整大小的功能讓 string版本的getline() 不需要指定要讀取多少個字符的參數
-
string 版本的 getline() 從輸入流中讀取字符, 并將其放入目標string 中, 直到發生下面幾種情況:
- 到達文件尾的輸入流的eofbit將被設置,這意味著方法fail()和eof()都將返回true;
- 遇到分界字符(默認為\n) 在這種情況下, 將把分界字符從輸入流中刪除,但不存儲它;
- 讀取的字符數達到最大允許值(string::npos和可供分配的內存字節數中較小的一個) 在這種情況下,將設置輸入流的failbit,這意味著方法fail()將返回true。
eofbit fail()等與 流狀態 相關, 將在 ~ C++輸入輸出和文件 -> 三. 使用cin進行輸入 -> 2. 流狀態 ~ 中講解
3. 使用字符串
-
字符串比較
string 類對全部6個關系運算符都進行了重載, 如果機器排列序列為ASCII碼, 那么數字字符 < 大寫字符 < 小寫字符;
對于每個關系運算符, 都以三種方式被重載, 以便將string對象和 另一個string對象,C風格字符串 進行比較 :#include <iostream> #include <exception> int main() { using namespace std; string snake1("cobra"); string snake2("coaal"); char snake3[20] = "cobra"; if (snake1 < snake2) // operator<(const string &, const string &) { cout << "snake1 < snake 2" << endl; } if (snake1 == snake3) // operator==(const string &, const char *) { cout << "snake1 == snake3" << endl; } if (snake3 != snake2) // operator!=(const char *, const string &) { cout << "snake3 != snake2" << endl; } system("pause"); return 0; }size() 和 length() 都返回字符串的字符數
length()成員來自較早版本的string類, 而size()則是為STL兼容性而添加的 -
表2 重載的find()方法字符串查找
string::npos是字符串可存儲的最大字符數, 通常是無符號int或long的最大取值;
string 庫還提供了相關的方法: rfind()、find_first_of()、find_last_of()、find_first_not_of()和find_last_not_of(),它們的重載函數特征標都與find()方法相同。rfind()方法查找子字符串或字符最后一次出現的位置;find_first_of()方法在字符串中查找參數中任何一個字符首次出現的位置。例如,下面的語句返回 r 在“cobra”中的位置(即索引3),因為這是“hark”中各個字母在“cobra”首次出現的位置:方 法 原 型
描 述
size_type find(const string & str,
size_type pos = 0)const從字符串的pos位置開始,查找子字符串str。如果找到,則返回該子字符串首次出現時其首字符的索引;否則,返回string :: npos
size_type find(const char * s,
size_type pos = 0)const從字符串的pos位置開始,查找子字符串s。如果找到,則返回該子字符串首次出現時其首字符的索引;否則,返回string :: npos
size_type find(const char * s,
size_type pos, size_type n)從字符串的pos位置開始,查找s的前n個字符組成的子字符串。如果找到,則返回該子字符串首次出現時其首字符的索引;否則,返回string :: npos
size_type find(char ch,
size_type pos = 0)const從字符串的pos位置開始,查找字符ch。如果找到,則返回該字符首次出現的位置;否則,返回string :: npos
int where = snake1.find_first_of("hark");find_last_of()方法的功能與此相同,只是它查找的是最后一次出現的位置。因此,下面的語句返回a在“cobra”中的位置:
int where = snake1.find_last_of("hark");find_first_not_of()方法在字符串中查找第一個不包含在參數中的字符,因此下面的語句返回c在“cobra”中的位置,因為“hark”中沒有c:
int where = snake1.find_first_not_of("hark");
4. 其他string類方法
-
很多, 就蘿莉一些, 再挑幾個講. 其他的用到的時候就知道了
a) =,assign() //賦以新值 b) swap() //交換兩個字符串的內容 c) +=,append(),push_back() //在尾部添加字符 d) insert() //插入字符 e) erase() //刪除字符 f) clear() //刪除全部字符 g) replace() //替換字符 h) + //串聯字符串 i) ==,!=,<,<=,>,>=,compare() //比較字符串 j) size(),length() //返回字符數量 k) max_size() //返回字符的可能最大個數 l) empty() //判斷字符串是否為空 m) capacity() //返回重新分配之前的字符容量 n) reserve() //保留一定量內存以容納一定數量的字符 o) [], at() //存取單一字符 at()索引無效時,會拋出out_of_range異常 p) >>,getline() //從stream讀取某值 q) << //將謀值寫入stream r) copy() //將某值賦值為一個C_string s) c_str() //將內容以C_string返回 不可修改 t) data() //將內容以字符序列指針形式返回 可修改 u) substr() //返回某個子字符串 v)查找函數 w)begin() end() //提供類似STL的迭代器支持 x) rbegin() rend() //逆向迭代器 y) get_allocator() //返回配置器 -
compare 返回值意義(吾用區間表示法表示):[小于,0,大于] , 0:相等
string s("abcd"); s.compare("abcd"); //返回0 s.compare("dcba"); //返回一個小于0的值 s.compare("ab"); //返回大于0的值 s.compare(s); //相等 //參數1:下標 2:字符個數 3:比較的對象 4:下標 5:字符個數 s.compare(0,2,s,2,2); //用"ab"和"cd"進行比較 小于零 //參數1:下標 2:字符個數 3:比較的對象 4:字符個數 s.compare(1,2,"bcx",2); //用"bc"和"bc"比較。 -
assign 重新分配
s.assign(str); //字面意思 //參數1:目標 2:下標 3:字符數 s.assign(str,1,3);//如果str是"iamangel" 就是把"ama"賦給字符串 s.assign(str,2,string::npos);//把字符串str從索引值2開始到結尾賦給s s.assign("gaint"); //字面意思 s.assign("nico",5);//把’n’ ‘I’ ‘c’ ‘o’ ‘’賦給字符串 s.assign(5,'x');//把五個x賦給字符串 -
append 附加
s.append(str); s.append(str,1,3);//不解釋了 同前面的函數參數assign的解釋 s.append(str,2,string::npos)// s.append("my name is jiayp"); s.append("nico",5); s.append(5,'x'); s.push_back('a');//這個函數只能增加單個字符 -
insert 插入
s.insert(0,"my name"); s.insert(1, "m"); s.insert(1,str); -
replace erase 替換和擦除
s.replace(1,2,"nternationalizatio");//從索引1開始的2個替換成后面的C_string或string對象 s.erase(13);//從索引13開始往后全刪除 s.erase(7,5);//從索引7開始往后刪5個 -
substr 返回子字符串(新的string)
s.substr();//返回s的全部內容 s.substr(11);//從索引11往后的子串 s.substr(5,6);//從索引5開始6個字符 -
copy 復制并替換目標中原有的字符
char str1[20] = "Hello"; char str2[20] {0}; string sl = "World"; //參數1:目標對象 2:要copy的字符數 3:從sl的下標?開始 sl.copy(str1, 5, 2);// cout << str1 << endl; -
方法capacity()返回當前分配給字符串的內存塊的大小,而reserve()方法讓您能夠請求增大內存塊
#include <iostream> #include <string> int main() { using namespace std; string empty; string small = "bit"; string larger = "Elephants are a girl's best friend"; cout << "Sizes:\n"; cout << "\tempty: " << empty.size() << endl; cout << "\tsmall: " << small.size() << endl; cout << "\tlarger: " << larger.size() << endl; cout << "Capacities:\n"; cout << "\tempty: " << empty.capacity() << endl; cout << "\tsmall: " << small.capacity() << endl; cout << "\tlarger: " << larger.capacity() << endl; empty.reserve(50); cout << "Capacity after empty.reserve(50): " << empty.capacity() << endl; return 0; } -
如果您有string對象,但需要C風格字符串,該如何辦呢?
string filename; filename.c_str(); //返回c風格字符串
5. 字符串種類
-
本節將string類看作是基于char類型的。事實上,正如前面指出的,string庫實際上是基于一個模板類的:
template<class charT, class traits = char _traits<charT>, class Allocator = allocator<charT> > basic_string {...}; -
模板basic_string有4個具體化(特化),每個具體化都有一個typedef名稱:
typedef basic_string<char> string; typedef basic_string<wchar_t> wstring; typedef basic_string<char16_t> u16string; // C++11 typedef basic_string<char32_t> u32string ; // C++11這讓您能夠使用基于類型wchar_t、char16_t、char32_t和char的字符串。甚至可以開發某種類似字符的類,并對它使用basic_string類模板(只要它滿足某些要求)。traits類描述關于選定字符類型的特定情況,如如何對值進行比較。對于wchar_t、char16_t、char32_t和char類型,有預定義的char_traits模板具體化,它們都是traits的默認值。Allocator是一個管理內存分配的類。對于各種字符類型,都有預定義的allocator模板具體化,它們都是默認的。它們使用new和delete。
總結
以上是生活随笔為你收集整理的String 类和 STL (Standard Template Library)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十分钟教你在 k8s 中部署一个前后端应
- 下一篇: Unity3d_Rewired官方文档翻