Java有一个方便的拆分方法:
String str = "The quick brown fox";
String[] results = str.split(" ");
在C++中有没有一种简单的方法来实现这一点?
C++标准库算法非常普遍地基于迭代器,而不是具体的容器。 不幸的是,这使得很难在C++标准库中提供类似Java的拆分
函数,尽管没有人认为这样做会很方便。 但是它的返回类型是什么呢? std::vector
? 也许吧,但是我们被迫执行(可能是多余的和昂贵的)分配。
相反,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{}
);
Boost tokenizer类可以使这类事情变得非常简单:
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int, char**)
{
string text = "token, test string";
char_separator<char> sep(", ");
tokenizer< char_separator<char> > tokens(text, sep);
BOOST_FOREACH (const string& t, tokens) {
cout << t << "." << endl;
}
}
已为C++11更新:
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int, char**)
{
string text = "token, test string";
char_separator<char> sep(", ");
tokenizer<char_separator<char>> tokens(text, sep);
for (const auto& t : tokens) {
cout << t << "." << endl;
}
}
下面是一个非常简单的例子:
#include <vector>
#include <string>
using namespace std;
vector<string> split(const char *str, char c = ' ')
{
vector<string> result;
do
{
const char *begin = str;
while(*str != c && *str)
str++;
result.push_back(string(begin, str));
} while (0 != *str++);
return result;
}