最終更新:2026-10-12
C++ 文字列の 6 つの分割方法¶
開発では長い文字列を区切り文字で分割して、目的の文字列を取得することがよくあります。C++ の文字列分割はあまり便利ではないと言われますが、今回は文字列を分割する 5 つの方法をまとめてみます。
C++11 から C++20 までの書き方、および C 流の書き方を含みます。
以降の記事での解説を分かりやすくするため、まず関数プロトタイプを定義しておきます:
-
パラメータ:2 つの文字列。1 つは元の文字列、もう 1 つは区切り文字を表します
-
戻り値:文字列の配列
注:楽をしたい方向けに、完全なコードは星球から入手できます。
1.find による分割¶
1 つ目の方法は、よく使われる「まず区切り文字の位置を探し、文字列を分割して配列に追加する」というものです。そこから次のコードが生まれます。
nt start = 0;
int end = s.find(delim);
std::vector<std::string> result;
while (end != std::string::npos) {
result.push_back(s.substr(start, end - start));
start = end + delim.size();
end = s.find(delim, start);
}
result.push_back(s.substr(start, end - start));
この方法はさらに最適化できるでしょうか?
答えは Yes です。コードをよりエレガントに見せるため、すでに出力済みの部分文字列を毎回削除し、find のロジックは同じままにできます。
while (end != std::string::npos) {
result.push_back(s.substr(0, end));
s.erase(0, end + delim.size());
end = s.find(delim);
}
2.C++20 Ranges と Views による分割¶
C++20 では std::ranges::views::split() で区切り文字のビューを作成し、transform を使って各サブビューを std::string に変換できます。
auto split_transform_view = s | std::ranges::views::split(delim) |
std::ranges::views::transform([](auto&& str) {
return std::string(str.begin(), str.end());
});
とても簡単でしょう。分からなかったという方は、以前の C++20 の記事を読みに戻りましょう。
3.正規表現による分割¶
std::regex オブジェクトで区切り文字のパターンを構築し、std::sregex_token_iterator で正規表現パターンによって区切られた部分文字列を走査します。-1 はマッチしない文字列、すなわち区切り文字以外の文字列を抽出することを表します。
std::regex r(delim);
return {std::sregex_token_iterator(s.begin(), s.end(), r, -1),
std::sregex_token_iterator()};
4.istringstream による分割¶
getline は一度に 1 つの区切り文字しか渡せないため、分割した後で、続く区切り文字をさらにスキップする必要があります。
std::istringstream ss(s);
while (std::getline(ss, token, *(it = delim.begin()))) {
result.push_back(token);
it++;
while (it != delim.end() && ss.peek() == *(it)) {
it++;
ss.get();
}
}
5.C 流の strtok による分割¶
strtok() で文字列をトークンに分割し、while ループで順番に取り出すだけです。
token = strtok((char*)s.c_str(), delim.c_str());
while (token != NULL) {
result.push_back(token);
token = strtok(NULL, delim.c_str());
}
以上がよく使われるいくつかの方法です。他にも方法はありますか?ぜひコメント欄でお聞かせください。この節の楽ちん版の完全なコードは星球から入手できます。
関連トピック¶
- CPython 拡張開発メモ | C++那些事
- libcurl C++ 開発メモ | C++那些事
- オープンソース C++ コードの読み方 | C++那些事
- ある面白い C++ コード | C++那些事
- C++ ループなしで 1-100 を出力 | C++那些事