【筆記】字串流 stringstream

簡介

有一個類型叫 iostream,它同時是輸入流也是輸出流,而 stringstream 正是一種 iostream。它不像標準流,有固定的輸出去向或輸入來源,簡單來講,它就是一個流水線,你可以從任何地方放東西進去、然後再把裡面的東西拿出來到任何地方。像是你就無法在程式中把標準輸出流的緩衝區裡的東西拿出來,你只能在 terminal 或它導向的檔案裡見到你放進標準輸出流的東西(就是你輸出的東西)。
WIWIHO 的競程筆記

簡單來說,就是可以將某個東西放進 stringstream,再把它拿出來,也不用判別它的資料型態。

應用

  • 是轉換資料型態的好幫手
  • 可以做字串切割

宣告

記得先引入 <sstream>

1
2
3
4
string str = "hi";
stringstream ss1;
stringstream ss2(str);
stringstream ss3(str);

例子

字串轉整數

如下,num 就被賦予值了

1
2
3
4
5
stringstream ss;
ss << "13934";
int num;
ss >> num;
cout << num << '\n';

有趣的是,它一樣會根據空格做切割,也就是說,給它一個這樣的字串 "3 7 5",流出一次就只會取到 3,所以如果要讀取全部數字,你需要跑三次。

1
2
3
4
5
6
7
8
9
stringstream ss;
ss << "3 7 5";
int num;
ss >> num;
cout << num << "\n";
ss >> num;
cout << num << "\n";
ss >> num;
cout << num << "\n";
Output
1
2
3
3
7
5

但假設你不知道有多少數字,你可以用 EOF 的方式讀取:

1
2
3
4
5
6
stringstream ss;
ss << "1 5 6 2 7 2 8 0 1 3 5 7";
int num;
while (ss >> num) {
cout << num << " ";
}
Output
1
1 5 6 2 7 2 8 0 1 3 5 7 

整數轉字串

其實使用方法都一樣,所以就不再多加贅述。

1
2
3
4
5
6
stringstream ss;
ss << 123 << 527;
string str;
while (ss >> str) {
cout << str << " ";
}
Output
1
123527

不過這裡要注意的是,如過把數字連續放進去的話,會直接連起來。也就是說可以推測 stringstream 應該也是把數字當字串在處理。所以如果要將數字各個獨立存取,那就要加一個含空白字元(字串)來做切割,這樣就不會連在一起。

1
2
3
4
5
6
stringstream ss;
ss << 123 << " " << 527;
string str;
while (ss >> str) {
cout << str << " ";
}
Output
1
123 527

其實也能轉成其他資料型態例如:浮點數、布林值等等。

字串切割

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string str;  // 原字串
// 用 getline 是因為怕該字串有空格
getline(cin, str);

stringstream ss(str);
// 指定分割字元
char c;
// 用 get 是因為可以輸入空白字元
// 若不會用到空白,也可以用 cin >> c;
cin.get(c);

string substr;
while (getline(ss, substr, c)) {
cout << substr << '\n';
}
Sample Input 1
1
2
apple banana cat
a
Sample Output 1
1
2
3
4
5
6

pple b
n
n
c
t
Sample Input 2
1
2
apple banana cat

Sample Output 2
1
2
3
apple
banana
cat