10.7 string:更好用的字串型態
8.6 學 C 字串時說過,C++ 準備了一個更方便的字串型態——現在正式登場。string 是專門裝字元序列的容器,可以想成「裝 char 的 vector」再加上一整套字串專屬功能。它定義在 <string> 裡。
¶宣告與初始化
string a; // 空字串
string b = "AACPSCHOOL"; // 用字面常數初始化
string c = b; // 複製另一個字串(跟 vector 一樣是完整複製)
string d(5, 'A'); // 5 個 'A':"AAAAA"
char cs[] = "hello";
string e = cs; // C 字串也能直接變成 string
¶讀入與輸出
cin >> s 的規則跟 8.7 讀 C 字串一模一樣:跳過空白換行,讀一個「單詞」;cout << s 整串印出;搭配上冊 4.8 的 EOF 模式 while (cin >> s) 也照舊。但用起來的感覺完全不同:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string s; // 不用宣告大小!
cin >> s; // 跟 8.7 一樣:跳過空白,讀一個單詞
cout << s.size() << '\n'; // 長度直接問,不用數 '\0'
s[0] = toupper(s[0]); // s[i] 是 char:第八單元的工具全部適用
cout << s << '\n';
return 0;
}
執行結果(輸入 hello):
5
Hello
s[i] 拿到的就是 char——第八單元的所有本事(c - '0'、isdigit、toupper……)在 string 身上全部適用。
¶跟 C 字串比一比
| 事情 | C 字串(8.6~8.8) | string |
|---|---|---|
| 宣告 | char s[105];(先猜上限,幫 '\0' 留位) |
string s;(大小自動長) |
| 長度 | strlen(s)(O(n),得先存變數) |
s.size()(O(1)) |
| 複製 | strcpy(t, s) |
t = s |
| 比較 | strcmp(s, t) == 0 |
s == t、s < t |
| 串接 | strcat(t, s) |
t += s |
三大解放:不用管 '\0'、不用預先猜大小、= 和 == 直接用(string 是容器,享有 10.6 那套待遇)。C 字串還是會出現在別人的程式碼和教材裡,看得懂即可;自己寫,以後一律 string。
¶string 的陣列
跟 vector 一樣,string 也能宣告成陣列——8.10 的字元網格從此換個活法,一格住一整列:
#include <iostream>
#include <string>
using namespace std;
const int MAX_H = 105;
string g[MAX_H]; // string 的陣列:一格住一整列
int main() {
int h, w;
cin >> h >> w;
for (int i = 0; i < h; i++) {
cin >> g[i]; // 一次讀一整列,不用煩惱 '\0'
}
int cnt = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (g[i][j] == '#') cnt++;
}
}
cout << cnt << '\n';
return 0;
}
執行結果(輸入 2 3 與 #.#、..#):
3
跟 8.10 的範例是同一個任務——但第二維多開一格、'\0' 住哪的煩惱,全部消失了。想連列數都不固定,vector<string> 也隨時候教。
動手試試看:解掉反向字串序列——把「string 的陣列」實際用起來:收下一串字串、反向處理後交回,函式參數正是 const vector<string>&(10.6 傳參考的實戰)。