如何迭代由空格分隔的单词组成的字符串中的单词?
注意,我对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);
}
作为一个业余爱好者,这是我想到的第一个解决方案。我有点好奇,为什么我还没有在这里看到类似的解决方案,是不是我的做法有根本问题?
#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
如果您希望按某些字符分割字符串,可以使用
#include<iostream>
#include<string>
#include<vector>
#include<iterator>
#include<sstream>
#include<string>
using namespace std;
void replaceOtherChars(string &input, vector<char> ÷rs)
{
const char divider = dividers.at(0);
int replaceIndex = 0;
vector<char>::iterator it_begin = dividers.begin()+1,
it_end= dividers.end();
for(;it_begin!=it_end;++it_begin)
{
replaceIndex = 0;
while(true)
{
replaceIndex=input.find_first_of(*it_begin,replaceIndex);
if(replaceIndex==-1)
break;
input.at(replaceIndex)=divider;
}
}
}
vector<string> split(string str, vector<char> chars, bool missEmptySpace =true )
{
vector<string> result;
const char divider = chars.at(0);
replaceOtherChars(str,chars);
stringstream stream;
stream<<str;
string temp;
while(getline(stream,temp,divider))
{
if(missEmptySpace && temp.empty())
continue;
result.push_back(temp);
}
return result;
}
int main()
{
string str ="milk, pigs.... hot-dogs ";
vector<char> arr;
arr.push_back(' '); arr.push_back(','); arr.push_back('.');
vector<string> result = split(str,arr);
vector<string>::iterator it_begin= result.begin(),
it_end= result.end();
for(;it_begin!=it_end;++it_begin)
{
cout<<*it_begin<<endl;
}
return 0;
}
最小的解决方案是一个函数,它将std::字符串和一组分隔符(作为std::string)作为输入,并返回std:::字符串的std::向量。
#include <string>
#include <vector>
std::vector<std::string>
tokenize(const std::string& str, const std::string& delimiters)
{
using ssize_t = std::string::size_type;
const ssize_t str_ln = str.length();
ssize_t last_pos = 0;
// container for the extracted tokens
std::vector<std::string> tokens;
while (last_pos < str_ln) {
// find the position of the next delimiter
ssize_t pos = str.find_first_of(delimiters, last_pos);
// if no delimiters found, set the position to the length of string
if (pos == std::string::npos)
pos = str_ln;
// if the substring is nonempty, store it in the container
if (pos != last_pos)
tokens.emplace_back(str.substr(last_pos, pos - last_pos));
// scan past the previous substring
last_pos = pos + 1;
}
return tokens;
}
用法示例:
#include <iostream>
int main()
{
std::string input_str = "one + two * (three - four)!!---! ";
const char* delimiters = "! +- (*)";
std::vector<std::string> tokens = tokenize(input_str, delimiters);
std::cout << "input = '" << input_str << "'\n"
<< "delimiters = '" << delimiters << "'\n"
<< "nr of tokens found = " << tokens.size() << std::endl;
for (const std::string& tk : tokens) {
std::cout << "token = '" << tk << "'\n";
}
return 0;
}