如何迭代由空格分隔的单词组成的字符串中的单词?
注意,我对C字符串函数或那种字符操作/访问不感兴趣。比起效率,我更喜欢优雅。我当前的解决方案:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string s = "Somewhere down the road";
istringstream iss(s);
do {
string subs;
iss >> subs;
cout << "Substring: " << subs << endl;
} while (iss);
}
这是我的版本获取了Kev的来源:
#include <string>
#include <vector>
void split(vector<string> &result, string str, char delim ) {
string tmp;
string::iterator i;
result.clear();
for(i = str.begin(); i <= str.end(); ++i) {
if((const char)*i != delim && i != str.end()) {
tmp += *i;
} else {
result.push_back(tmp);
tmp = "";
}
}
}
之后,调用函数并执行以下操作:
vector<string> hosts;
split(hosts, "192.168.1.2,192.168.1.3", ',');
for( size_t i = 0; i < hosts.size(); i++){
cout << "Connecting host : " << hosts.at(i) << "..." << endl;
}
我编写了以下代码。您可以指定分隔符,它可以是字符串。结果类似于Java的String.split,结果中包含空字符串。
例如,如果我们调用split(“ABCPICKABCANYABCTWO:ABC”,“ABC”),结果如下:
0 <len:0>
1 PICK <len:4>
2 ANY <len:3>
3 TWO: <len:4>
4 <len:0>
代码:
vector <string> split(const string& str, const string& delimiter = " ") {
vector <string> tokens;
string::size_type lastPos = 0;
string::size_type pos = str.find(delimiter, lastPos);
while (string::npos != pos) {
// Found a token, add it to the vector.
cout << str.substr(lastPos, pos - lastPos) << endl;
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = pos + delimiter.size();
pos = str.find(delimiter, lastPos);
}
tokens.push_back(str.substr(lastPos, str.size() - lastPos));
return tokens;
}
值得一提的是,这里有另一种从输入字符串中提取令牌的方法,仅依赖于标准库设施。这是STL设计背后力量和优雅的一个例子。
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
int main() {
using namespace std;
string sentence = "And I feel fine...";
istringstream iss(sentence);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
ostream_iterator<string>(cout, "\n"));
}
可以使用相同的通用复制算法将提取的令牌插入到容器中,而不是将其复制到输出流中。
vector<string> tokens;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(tokens));
…或直接创建矢量:
vector<string> tokens{istream_iterator<string>{iss},
istream_iterator<string>{}};
根据Galik的回答,我做了这个。这大部分都在这里,所以我不必一遍又一遍地写。C++仍然没有原生拆分函数,这真是太疯狂了。特征:
应该很快。容易理解(我认为)。合并空节。使用多个分隔符(例如“\r\n”)很简单
#include <string>
#include <vector>
#include <algorithm>
std::vector<std::string> split(const std::string& s, const std::string& delims)
{
using namespace std;
vector<string> v;
// Start of an element.
size_t elemStart = 0;
// We start searching from the end of the previous element, which
// initially is the start of the string.
size_t elemEnd = 0;
// Find the first non-delim, i.e. the start of an element, after the end of the previous element.
while((elemStart = s.find_first_not_of(delims, elemEnd)) != string::npos)
{
// Find the first delem, i.e. the end of the element (or if this fails it is the end of the string).
elemEnd = s.find_first_of(delims, elemStart);
// Add it.
v.emplace_back(s, elemStart, elemEnd == string::npos ? string::npos : elemEnd - elemStart);
}
// When there are no more non-spaces, we are done.
return v;
}