2009-12-16 41 views
0

我在书“Accelerated C++”(第6.1.1章)中找到了下面的代码,但我无法编译它。问题在于find_if行。我有必要的包括(矢量,字符串,算法,cctype)。任何想法?使用find_if分割字符串

感谢,贾巴

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 iter; 
    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; 
} 
+0

如何对这些编译错误? :) – GManNickG 2009-12-16 23:35:02

+0

确实。在包含和'使用命名空间标准;'扔在这里完美地编译;请告诉我们你有什么不同。 – ephemient 2009-12-16 23:42:47

+0

这个例子在这里编译。你应该给出一个完整的最小例子。 – anno 2009-12-16 23:46:38

回答

1

有一个在你发布的代码没有问题。 真正的代码有一个非常明显的问题,你链接到:is_spacespace成员功能,并且他们不能被称为没有Split2的实例。但是这个要求没有任何意义,所以至少你应该使这些功能静态

(其实这并没有太大的意义split_v3是一个成员函数或者什么有一个名为Split2实现在具有只是一个免费的功能类 - 可能是在一个命名空间。?)

+0

要解决此问题:使用结构作为谓词而不是函数。如果您将其声明为嵌套类,那么您仍然可以获得“封装”。 – pmr 2009-12-17 01:00:52

+0

你说得对,如果我把它们放在课堂上,那些功能必须是静态的。我更喜欢把所有东西都放在类中(我之前使用过Java)。这是一个坏习惯吗? 感谢您的回答,问题解决了。 – Jabba 2009-12-17 01:04:17

+0

pmr:你能为此发布一个例子吗? – Jabba 2009-12-17 01:06:12

0

副手,我会说这大概应该是

i = str.find_if(... 
j = str.find_if(... 
+0

Nope,'template InputIterator find_if(InputIterator first,InputIterator last,Predicate pred);''是一个内嵌函数,作用于''中定义的迭代器 - 不是字符串或向量的方法或类似的东西那。 – ephemient 2009-12-16 23:44:12

1

根据要求:

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); } 
    }; 

将它们与std::find_if(it, it2, space())std::find_if(it, it2, not_space()一起使用。
请注意,not_space具有默认构造空间作为成员变量。在每次调用bool not_space::operator()时构建空间可能并不明智,但编译器可能会考虑到这一点。如果重载operator()的语法让你感到困惑,并且你想知道更多关于使用structs作为Predicates的信息,你应该看看操作符重载和STL的一些指导。

+0

当你可以使用''''的'ptr_fun(isspace)'和'not1(ptrfun(isspace))'时,为什么还要用'space'和'not_space'? – ephemient 2009-12-17 02:20:49

+0

由于'isspace'(来自)预计可以将int转换为容易出错的'unsigned char'。这样你整齐地包装难度,以便易于使用。 – 2009-12-17 10:59:39

1

更STL状的方式写这篇,

#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; 
} 
+0

小点,但应避免使用命名空间标准; – 2009-12-17 11:00:28

+0

我通常也避免使用'命名空间',但是对于这个简短的例子,我更愿意避免超过80列的行。 – ephemient 2009-12-17 15:02:56