如何迭代由空格分隔的单词组成的字符串中的单词?
注意,我对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);
}
这是我写的一个函数,帮助我做了很多事情。它在为WebSocket做协议时帮助了我。
using namespace std;
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
vector<string> split ( string input , string split_id ) {
vector<string> result;
int i = 0;
bool add;
string temp;
stringstream ss;
size_t found;
string real;
int r = 0;
while ( i != input.length() ) {
add = false;
ss << input.at(i);
temp = ss.str();
found = temp.find(split_id);
if ( found != string::npos ) {
add = true;
real.append ( temp , 0 , found );
} else if ( r > 0 && ( i+1 ) == input.length() ) {
add = true;
real.append ( temp , 0 , found );
}
if ( add ) {
result.push_back(real);
ss.str(string());
ss.clear();
temp.clear();
real.clear();
r = 0;
}
i++;
r++;
}
return result;
}
int main() {
string s = "S,o,m,e,w,h,e,r,e, down the road \n In a really big C++ house. \n Lives a little old lady. \n That no one ever knew. \n She comes outside. \n In the very hot sun. \n\n\n\n\n\n\n\n And throws C++ at us. \n The End. FIN.";
vector < string > Token;
Token = split ( s , "," );
for ( int i = 0 ; i < Token.size(); i++) cout << Token.at(i) << endl;
cout << endl << Token.size();
int a;
cin >> a;
return a;
}
最小的解决方案是一个函数,它将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;
}
最近我不得不将一个骆驼大小写的单词拆分成子单词。没有分隔符,只有大写字符。
#include <string>
#include <list>
#include <locale> // std::isupper
template<class String>
const std::list<String> split_camel_case_string(const String &s)
{
std::list<String> R;
String w;
for (String::const_iterator i = s.begin(); i < s.end(); ++i) { {
if (std::isupper(*i)) {
if (w.length()) {
R.push_back(w);
w.clear();
}
}
w += *i;
}
if (w.length())
R.push_back(w);
return R;
}
例如,这将“AQueryTrades”拆分为“A”、“Query”和“Trades”。该函数适用于窄字符串和宽字符串。因为它尊重当前的语言环境,所以将“RaumfahrtÜberwachungsVerordnung”分为“Raumfahrt”、“Überwachungs”和“Verordnug”。
注意std::upper应该真正作为函数模板参数传递。然后,此函数的更广义的from也可以在分隔符(如“、”、“;”或“”)处拆分。