split a string using find_if
I found the following code in the book "Accelerated C++" (Chapter 6.1.1), but I can't compile it. The problem is with the find_if
lines. I have the necessary includes (vector, string, algorithm, cctype). Any idea?
Thanks, Jabba
bool space(char c) {
return isspace(c);
}
bool not_space(char c) {
return !isspace(c);
}
vector<string> split_v3(const string& str)
{
typedef string::const_iterator i开发者_如何学运维ter;
vector<string> ret;
iter i, j;
i = str.begin();
while (i != str.end())
{
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
j = find_if(i, str.end(), space);
// copy the characters in [i, j)
if (i != str.end()) {
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
Writing this in a more STL-like manner,
#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
using namespace std;
template<class P, class T>
void split(const string &str, P pred, T output) {
for (string::const_iterator i, j = str.begin(), str_end = str.end();
(i = find_if(j, str_end, not1(pred))) != str_end;)
*output++ = string(i, j = find_if(i, str_end, pred));
}
int main() {
string input;
while (cin >> input) {
vector<string> words;
split(input, ptr_fun(::isspace), inserter(words, words.begin()));
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
}
return 0;
}
There is no problem in the code you posted. There is a very obvious problem with the real code you linked to: is_space
and space
are member functions, and they cannot be called without an instance of Split2. This requirement doesn't make sense, though, so at least you should make those functions static.
(Actually it doesn't make much sense for split_v3 to be a member function either. What does having a class called Split2 achieve over having just a free function - possibly in a namespace?)
As requested:
class SplitV2 {
public:
void foo();
private:
struct space { bool operator() (char c) { return isspace(c); } };
struct not_space {
Split2::space space;
bool operator() (char c) { return !space(c); }
};
Use them with std::find_if(it, it2, space())
or std::find_if(it, it2, not_space()
.
Notice that not_space has a default constructed space as a member variable. It may be not wise to construct space in every call to bool not_space::operator()
but maybe the compiler could take care of this. If the syntax for overloading operator() confuses you and you would like to know more about using structs as Predicates you should have a look at operator overloading and some guidelines to the STL.
Off hand, I would say it should probably be
i = str.find_if( ...
j = str.find_if( ...
精彩评论