如何迭代由空格分隔的单词组成的字符串中的单词?
注意,我对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);
}
我喜欢下面的代码,因为它将结果放入一个向量中,支持字符串作为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()都非常有用。
我们可以在c++中使用strtok,
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char str[]="Mickey M;12034;911416313;M;01a;9001;NULL;0;13;12;0;CPP,C;MSC,3D;FEND,BEND,SEC;";
char *pch = strtok (str,";,");
while (pch != NULL)
{
cout<<pch<<"\n";
pch = strtok (NULL, ";,");
}
return 0;
}
短而优雅
#include <vector>
#include <string>
using namespace std;
vector<string> split(string data, string token)
{
vector<string> output;
size_t pos = string::npos; // size_t to avoid improbable overflow
do
{
pos = data.find(token);
output.push_back(data.substr(0, pos));
if (string::npos != pos)
data = data.substr(pos + token.size());
} while (string::npos != pos);
return output;
}
可以使用任何字符串作为分隔符,也可以与二进制数据一起使用(std::string支持二进制数据,包括空值)
使用:
auto a = split("this!!is!!!example!string", "!!");
输出:
this
is
!example!string
作为一个业余爱好者,这是我想到的第一个解决方案。我有点好奇,为什么我还没有在这里看到类似的解决方案,是不是我的做法有根本问题?
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> split(const std::string &s, const std::string &delims)
{
std::vector<std::string> result;
std::string::size_type pos = 0;
while (std::string::npos != (pos = s.find_first_not_of(delims, pos))) {
auto pos2 = s.find_first_of(delims, pos);
result.emplace_back(s.substr(pos, std::string::npos == pos2 ? pos2 : pos2 - pos));
pos = pos2;
}
return result;
}
int main()
{
std::string text{"And then I said: \"I don't get it, why would you even do that!?\""};
std::string delims{" :;\".,?!"};
auto words = split(text, delims);
std::cout << "\nSentence:\n " << text << "\n\nWords:";
for (const auto &w : words) {
std::cout << "\n " << w;
}
return 0;
}
http://cpp.sh/7wmzy