2009-12-16 46 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