tags: tgirc早修book

string 字串

宣告與賦值

#include<string> //string標頭檔,內含多種營養函式(? string str1; //宣告一個名為str1的string容器 //僅在c++可用,C語言未提供此型態 char str2[10]; //宣告一個名為str2的char陣列 //如果是使用C語言就只能用char陣列,沒法用string型態 str = "Hello world!"; //把"Hello world!"指定給str

使用 string 型態時,建議引入 <string> 標頭檔。
雖然現在不需要此標頭檔,也能宣告 string 及使用一些基本功能,不過一些功能還是要引入此標頭檔才能使用。

(嚴格來說 string 不算是一種型態,而是一種容器,不過現階段就先暫時先把它當成一種形態就好)

基本操作

比較兩字串內容

如果要看內容是否相同,直接用 == 就好了,與 int 等型態操作方式相同。
至於 >< 也能用,不過比較順序是按照字典序來排列。

存取第n個字元

就像陣列一樣,可以直接以 str[n] 的方式處理,但存取超過陣列範圍的字元會出問題。
保險起見可以使用 .at(n),會有邊界檢查。如果超出範圍的話,雖然編譯時會給過,但執行時它會拋出一個 out_of_range 例外並終止程式。

str = "Hello world!"; cout << str[4] << '\n'; cout << str.at(4) << '\n'; cout << str.at(15) << '\n'; //超出str範圍 //拋出exception: throws: out_of_range cout << str[4] << '\n'; cout << str.at(4) << '\n';

輸出如下:

o
o

使用 .at() 的穩定性較高,但一般時候其實用 str[n] 就好了,效率會比較好。

取得字串長度

使用 .size() 或是 .length() 兩者,在 string 上不會有明顯差異。
需要注意的是別忘了後面的括號 ()。

str = "Hello world!"; int S,L; S = str.size(); //把str的大小使用.size()指定給S L = str.length(); //把str的大小使用.length()指定給S cout << S << ' ' << L;

輸出如下:

12 12

串接兩字串

可以使用 + 來串接兩字串,或是使用 .append(str) 來處理。
建議用 + 比較方便。

A = "Hello"; B = "Hello"; A += " world!"; //使用+來進行" world!"串接 B.append(" world!"); //或是使用.append() 把" world!"串接到A與B後 cout << A << '\n' << B;

輸出如下:

Hello world!
Hello world!

string 轉 int、int 轉 string

使用 to_string(n) 則可以將 n 轉為字串型態。
反過來說,stoi(str) 可以將 str 字串的內容轉為 int,而因為型態變為 int,開頭的 0 就會消失了

string str1 = "0324",str2; int n1 = 135,n2; n2 = stoi(str1); //將str1轉為int型態指定給n2 str2 = to_string(n1); //將n1轉為string型態指定給str2 cout << str2 << ' ' << n2;

輸出如下:

135 324
//str1原為"0324",轉為int後因為首位不會是0,所以變成324

取子字串

使用 .substr(x,n) 來取得 x 開始的 n 個字組成的子字串。

str1 = "Hello world!"; cout << str1.substr(6, 5); //從str1的第6個字開始取5個字元

輸出如下:

world

插入、取代與刪除字串

使用 .insert(x,str) 在指定位置 x 插入 str。
取代則是用 .replace(x,n,str),把 x 開始的 n 個字元替換成 str。
刪除某段就用 .erase(x,n),把從 x 開始的 n 個字元刪掉。

切記,string 跟陣列一樣,第一個字元的位置是 0 而不是 1。

str = "Hello world!"; str.insert(5, " John"); //Hello John world! cout << str << '\n'; str.replace(6, 4, "Maria"); //Hello Maria world! cout << str << '\n'; str.erase(5, 6); //Hello world! cout<<str;

輸出如下:

Hello John world!
Hello Maria world!
Hello world!

尋找字串中指定字串

使用 .find(str,n) 來尋找指定字串,回傳值為從n開始,找到的第一個str的開頭位置。
如果沒找到的話,則會回傳 string::npos。

str = "Hello world Hello"; if( str.find("Hello",0) != string::npos ){ //find("Hello",0) 不等於 string::npos //找到第一個"Hello"在第0個位置 cout << str.find("Hello",0) << '\n'; } else cout << "Not found!"; if( str.find("PPAP",0) != string::npos ){ cout << str.find("PPAP",0) << '\n'; } else cout << "Not found!"; //find("PPAP",0) 等於 string::npos //也就是找不到"PPAP"

輸出如下:

0
Not found!

反轉字串

這個是搭配 reverse(a, b) 函式來使用的,比較特別的是 a 跟 b 要傳入的是位置

如果要從 str 的開頭到結尾反轉,那 a 就是 str.begin(),代表 str 開頭的位置,而 b 則是 str.end(),代表 str 的結尾位置。

而如果是從第二個字元開始,那就把 a 換成 str.begin() + 1
如果只翻轉到倒數第二個,那就把 b 換成 str.end()-1,簡而言之,往後一個就 +1,往前一個就 -1。

如果要使用 reverse(),記得要引入 <algorithm> 標頭檔。

#include <algorithm> //包含了reverse()在內 . . . str = "Hello world!"; reverse(str.begin(), str.end()); //由str的第一個至最後一個反轉 cout << str << '\n';

輸出如下:

!dlrow olleH

使用 getline 進行整行輸入

一般使用 cin 輸入字串時,每遇到空格或換行,就會判斷為結束輸入。
但如果需要輸入一個文章,或是一段完整句子, cin 就無法完整輸入,因此會需要用到 getline

string s; getline(cin, s); cout << s << '\n';

使用 getline() 輸入不會被空格截斷,每遇到換行會先接收換行的指令,再跳到下一個輸入
可以參考以下例子

範例 1

cin >> a; getline(cin, str); cout << a << '\n' << str;

在這個例子中,我們輸入了 a 以後,還沒輸入字串程式就結束了

這是因為 cin 完最後的位子在 3 的後一格,所以 getline 讀到的是換行,而 getline 遇到換行會停下。

所以要輸入一段字串的話,要使用兩次 getline()(或是 gets()getchar())。
第一個吃掉換行,第二格才是輸入你要輸入的字串

cin >> a; getline(); getline(cin, str); cout << a << '\n' << str;