C++でコンマ区切りの文字列を解析します
この投稿では、C++でコンマ区切りの文字列を解析する方法について説明します。
1.文字列ストリームの使用
カンマ区切りの文字列を分割する標準的な解決策は、 std::stringstream
。以下は、一度に1文字を読み取り、直接の文字(つまり、コンマ)を破棄することによってその使用法を示しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <vector> #include <string> #include <sstream> using namespace std; vector<int> split(const string &str, char sep) { vector<int> tokens; int i; stringstream ss(str); while (ss >> i) { tokens.push_back(i); if (ss.peek() == sep) { ss.ignore(); } } return tokens; } int main() { string str = "1,2,3,4,5"; char sep = ','; vector<int> tokens = split(str, sep); for (auto &i: tokens) { cout << i << ' '; } return 0; } |
出力:
1 2 3 4 5
コードは、ifステートメントの代わりにwhileループを使用して、文字列内の複数の連続する区切り文字または空白を処理するように簡単に拡張できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <vector> #include <string> #include <sstream> using namespace std; vector<int> split(const string &str, char sep) { vector<int> tokens; int i; stringstream ss(str); while (ss >> i) { tokens.push_back(i); while (ss.peek() == sep || ss.peek() == ' ') { ss.ignore(); } } return tokens; } int main() { string str = "1, 2, 3, 4,, 5"; char sep = ','; vector<int> tokens = split(str, sep); for (auto &i: tokens) { cout << i << ' '; } return 0; } |
出力:
1 2 3 4 5
上記の両方のソリューションは、結果を整数vectorに入れて返します。コードを簡単に変更して、文字列のvectorを作成できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <iostream> #include <vector> #include <algorithm> #include <string> #include <sstream> using namespace std; vector<string> split(const string &str, char sep) { vector<string> tokens; string token; stringstream ss(str); while (getline(ss, token, ',')) { token.erase(remove_if(token.begin(), token.end(), ::isspace), token.end()); if (!token.empty()) { tokens.push_back(token); } } return tokens; } int main() { string str = "1, 2,3,4,,5"; char sep = ','; vector<string> tokens = split(str, sep); for (auto &s: tokens) { cout << s << ' '; } return 0; } |
出力:
1 2 3 4 5
2.使用する std::string::find
関数
別の解決策は、 std::string::find
文字列内の区切り文字の次の位置を取得し、最後の区切り文字位置と現在の区切り文字位置の間にある部分文字列をvectorに挿入する関数。
次のコードは、整数のvectorを作成することでこれを示していますが、文字列のvectorを作成し、不正な入力(連続した区切り文字、空白など)を処理するように簡単に変更できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <iostream> #include <vector> #include <string> using namespace std; vector<int> split(const string &str, char sep) { vector<int> tokens; if (str.empty()) { return tokens; } size_t start = 0, end = 0; while ((end = str.find(sep, start)) != string::npos) { tokens.push_back(stoi(str.substr(start, end - start))); start = end + 1; } tokens.push_back(stoi(str.substr(start))); return tokens; } int main() { string str = "1,2,3,4,5"; char sep = ','; vector<int> tokens = split(str, sep); for (auto &i: tokens) { cout << i << ' '; } return 0; } |
出力:
1 2 3 4 5
3.正規表現を使用する
カンマ区切りの文字列を解析するためのもう1つのもっともらしい解決策は、正規表現を使用することです。正規表現は、シーケンスに対してパターンマッチングを実行するための標準化された方法です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <vector> #include <string> #include <regex> using namespace std; int main() { string str = "1, 2, 3,4, 5"; regex reg("[, ]+"); sregex_token_iterator iter(str.begin(), str.end(), reg, -1); sregex_token_iterator end; vector<string> tokens(iter, end); for (auto &s: tokens) { cout << s << ' '; } return 0; } |
出力:
1 2 3 4 5
4.Boostライブラリの使用
Boost C++ライブラリは、このタスクのためのいくつかのユーティリティクラスも提供します。 The Boost tokenizer classは、特定の文字を区切り文字として解釈することにより、シーケンスに含まれるトークンのビューを提供します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> #include <boost/tokenizer.hpp> using namespace std; using namespace boost; int main() { string str = "1,2,3,4,5"; char_separator<char> sep(", "); tokenizer<char_separator<char>> tokens(str, sep); for (string i: tokens) { cout << i << ' '; } return 0; } |
出力:
1 2 3 4 5
Boostライブラリは boost::algorithm::split 式をトークン化する関数。これは、 strtok
Cで機能します boost::algorithm::split
関数は、入力シーケンスをトークンに分割し、述語を使用して指定された区切り文字で区切ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <string> #include <vector> #include <iostream> #include <boost/algorithm/string.hpp> using namespace std; using namespace boost::algorithm; int main() { string str = "1,2,3,4,5"; vector<string> tokens; split(tokens, str, is_any_of(",")); for (string i: tokens) { cout << i << ' '; } return 0; } |
出力:
1 2 3 4 5
これで、C++でコンマ区切りの文字列を解析できます。