1. ホーム
  2. c++

[解決済み] C++で文字列をトークン化するには?

2022-03-21 04:20:02

質問

Javaには便利な分割メソッドがあります。

String str = "The quick brown fox";
String[] results = str.split(" ");

C++で簡単にできる方法はありますか?

どのように解決するのですか?

C++標準ライブラリのアルゴリズムは、具象コンテナではなく、イテレータを中心にかなり普遍的に構成されています。残念ながら、このため、Javaのような split の関数は、それが便利であることを誰も主張しないにもかかわらず、C++標準ライブラリの中にある。しかし、その戻り値の型はどうなるのだろうか? std::vector<std::basic_string<…>> ? そうかもしれませんが、その場合、(潜在的に冗長でコストのかかる)アロケーションを実行することを余儀なくされます。

その代わりに、C++は、任意の複雑な区切り文字に基づいて文字列を分割する方法を多数提供していますが、他の言語のようにうまくカプセル化されているものはありません。多数の方法 ブログの記事全体を埋める .

最も簡単な方法は std::string::find に当たるまで std::string::npos を使用してコンテンツを抽出します。 std::string::substr .

空白で分割するための、より流動的な(慣用的ではあるが基本的な)バージョンは std::istringstream :

auto iss = std::istringstream{"The quick brown fox"};
auto str = std::string{};

while (iss >> str) {
    process(str);
}

使用方法 std::istream_iterator s また、文字列ストリームの内容は、そのイテレータ範囲コンストラクタを使ってベクターにコピーすることもできます。

複数のライブラリ(例えば Boost.Tokenizer ) は、特定のトークナイザーを提供しています。

より高度な分割を行うには正規表現が必要です。C++では std::regex_token_iterator は、特にこの目的のために

auto const str = "The quick brown fox"s;
auto const re = std::regex{R"(\s+)"};
auto const vec = std::vector<std::string>(
    std::sregex_token_iterator{begin(str), end(str), re, -1},
    std::sregex_token_iterator{}
);