ホームに戻る
出典 :
【C++入門】stringstreamで文字列を操作する方法 | 侍エンジニアブログ
目次 :

stringstream とは

文字列を操作するためのクラス。stringstream を用いることで、 といった操作を簡単に行うことができる。

基本

stringstream を使用する際は <sstream> のインクルードが必要となる。
また、stringstream は std 名前空間に属しており、名前空間の解決が必要となる。
#include <iostream> #include <string> //< string を使用するために必要 #include <sstream> //< stringstream を使用するために必要 void DoSomething() { // stringstream 型変数の宣言 std::stringstream ss; //< ss の中身 : 空文字列 // ss に文字列を追加 ss << "Hop"; //< ss の中身 : "Hop" // 複数の値を連結可能 // (ここでは " " と "Step" を連結) ss << " " << "Step"; //< ss の中身 : "Hop Step" // 数値も変換せずに連結可能 int num = 10; ss << " " << num; //< ss の中身 : "Hop Step 10" // str() で文字列を取得、画面に出力 std::cout << ss.str() << std::endl; }
実行結果
Hop Step 10
stringstream には << 演算子で任意の数の値を結合できる。また、数値をそのまま結合することができる。
これは標準出力ストリーム cout と同様である。
stringstream に格納された文字列を取り出す際は、str() 関数を用いる。

>> 演算子の振舞

>> 演算子は、stringstream から文字列を取り出す際に用いる。
ここで、格納された文字列に空白やタブ、改行などの「空白文字」が含まれる場合は、空白文字の直前までが抽出される
さらに次回の読み出し位置が(読み出した分 + 空白文字分)だけ進められる。 このため、>> 演算子を繰り返し用いることで、単語を順に取り出すことができる
#include <iostream> #include <string> #include <sstream> void DoSomething() { std::stringstream ss; ss << "Hop Step Dive"; //< ss の中身 : "Hop Step Dive" (1) // 1回目の >> std::string out1 ss >> out1; //< out1 の中身 : "Hop" (2) // 2回目の >> std::string out2 ss >> out2; //< out2 の中身 : "Step" (3) // 3回目の >> std::string out3 ss >> out3; //< out3 の中身 : "Dive" // str() で文字列を取得、画面に出力 std::cout << out1 << out2 << out3 << std::endl; }
実行結果
HopStepDive

何が起きているか

画像
(1)の実行直後、読み出し位置はストリームの先頭(既定値)にある。
>> で読み出しを行うと、最初の空白文字に遭遇するまでが読みだされるため、最初の単語である "Hop" (空白文字は読み出されない)が得られる。(2)
(2)を実行したことで読み出し位置は空白文字の次に進むため、>> で次の単語 "Step" が得られる。(3)

単語を数値として取り出す

>> を用いて単語を取り出す際、対象が数値に変換可能であれば、抽出先の変数に数値型を指定することで
その単語を数値として取り出すことができる
#include <iostream> #include <string> #include <sstream> void DoSomething() { std::stringstream ss; ss << "18 years old"; //< ss の中身 : "18 years old" // 1回目の >> int outnum; ss >> outnum; //< outnum == 18 // 2回目の >> std::string out2 ss >> out2; //< out2 の中身 : "years" // 3回目の >> std::string out3 ss >> out3; //< out3 の中身 : "old" }

文字の読み飛ばし( ignore() )

ignore() 関数は指定された文字数だけ読み出し位置を進める(読み飛ばす)。
値を指定しない場合は1文字を読み飛ばす。
#include <iostream> #include <string> #include <sstream> void DoSomething() { std::stringstream ss; ss << "2023/06/24"; //< ss の中身 : "2023/06/24" // 1回目の >> int year; ss >> year; //< year == 2023 (1) // 1 文字だけ読み飛ばす ss.ignore(); //< (2) // 2回目の >> int month; ss >> month; //< month == 6 (3) }

何が起きているか

画像
初回の >> で、最初の数値(2023)が抽出される。(1)
"2023" を読み出したため、読み出し位置は続く "/" に移動する。
ignore() 関数で "/" を読み飛ばすことで、読み出し位置が "/" の次に移動する。(2)
続く >> で "06" が読まれるが、数値に変換されるため 6 となる。(3)

行単位での文字列取得( getline() )

>> は空白文字で区切られた単語単位での取得となるが、getline() 関数を用いると改行文字で区切られた行単位の取得となる。
getline() を用いるには <iostream> のインクルードが必要。
#include <iostream> //< getline() に必要 #include <string> #include <sstream> void DoSomething() { std::stringstream ss; ss << "line01" << "\n" << "line02" << "\n" << "line03"; //< ss の中身 : line01\nline02\nline03 // 1回目の >> std::string out1 ss >> out1; //< out1 の中身 : "line01" // 2回目の >> std::string out2 ss >> out2; //< out2 の中身 : "line02" // 3回目の >> std::string out3 ss >> out3; //< out3 の中身 : "line03" }

書式の設定( setw() 、setfill() 、hex )

数値の表示桁数や、桁合わせ文字(パディング)を指定することができる。また、数値を16進数表記で格納することもできる。
これらの機能を使用するには <iomanip> のインクルードが必要。
#include <iomanip> //< 書式設定に必要 #include <iostream> #include <string> #include <sstream> void DoSomething() { // 数値を 4 桁表示で格納 std::stringstream ss1; ss1 << std::setw(4) << 1999 << "\n"; ss1 << std::setw(4) << 5; //< ss1 の中身 : 1999\n 5 // 数値を 4 桁表示で格納、空いた桁を '0' で埋める std::stringstream ss2; ss2 << std::setw(4) << std::setfill('0') << 1999 << "\n"; ss2 << std::setw(4) << 5; //< ss2 の中身 : 1999\n0005 // 数値を10進 / 16進表示で格納 std::stringstream ss3; ss3 << 127 << "\n"; ss3 << std::hex << 127; //< ss3 の中身 : 127\n7f std::cout << ss1.str(); << "\n"; std::cout << ss2.str(); << "\n"; std::cout << ss3.str(); << "\n"; }
実行結果
1999 5 1999 0005 127 7f
setw() 関数を用いることで桁数を指定できる。右詰めで格納され、上位桁は空白で埋められる。
setw() と共に setfill() 関数を用いることで、桁埋めに使用する文字を指定できる。setfill() の効果は永続することに注意。
上記の例では、setfill() を用いない ss1 は空白で桁が埋められるのに対し、ss2 では '0' で埋められている。
また、hex と組み合わせることで、数値を16進表記の文字列として格納できる。