ホームに戻る
出典 :
目次 :
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進表記の文字列として格納できる。