如何迭代由空格分隔的单词组成的字符串中的单词?
注意,我对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);
}
使用std::stringstream非常好,并且完全符合您的要求。如果您只是在寻找不同的方法,那么可以使用std::find()/std::find_first_of()和std::string::substr()。
下面是一个示例:
#include <iostream>
#include <string>
int main()
{
std::string s("Somewhere down the road");
std::string::size_type prev_pos = 0, pos = 0;
while( (pos = s.find(' ', pos)) != std::string::npos )
{
std::string substring( s.substr(prev_pos, pos-prev_pos) );
std::cout << substring << '\n';
prev_pos = ++pos;
}
std::string substring( s.substr(prev_pos, pos-prev_pos) ); // Last word
std::cout << substring << '\n';
return 0;
}
对于一个大得离谱而且可能是冗余的版本,可以尝试很多For循环。
string stringlist[10];
int count = 0;
for (int i = 0; i < sequence.length(); i++)
{
if (sequence[i] == ' ')
{
stringlist[count] = sequence.substr(0, i);
sequence.erase(0, i+1);
i = 0;
count++;
}
else if (i == sequence.length()-1) // Last word
{
stringlist[count] = sequence.substr(0, i+1);
}
}
它并不漂亮,但总的来说(除了标点符号和一系列其他错误)它是有效的!
根据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;
}
我喜欢下面的代码,因为它将结果放入一个向量中,支持字符串作为delim,并控制保持空值。但是,那时候看起来不太好。
#include <ostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
vector<string> split(const string& s, const string& delim, const bool keep_empty = true) {
vector<string> result;
if (delim.empty()) {
result.push_back(s);
return result;
}
string::const_iterator substart = s.begin(), subend;
while (true) {
subend = search(substart, s.end(), delim.begin(), delim.end());
string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(temp);
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}
int main() {
const vector<string> words = split("So close no matter how far", " ");
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
}
当然,Boost有一个split(),它的部分功能与此类似。而且,如果“空白”是指任何类型的空白,那么使用Boost的split和is_any_of()都非常有用。