разбить строку, используя find_if - PullRequest
0 голосов
/ 17 декабря 2009

Я нашел следующий код в книге «Ускоренный C ++» (глава 6.1.1), но не могу скомпилировать его. Проблема с линиями find_if. У меня есть необходимые включения (вектор, строка, алгоритм, cctype). Есть идеи?

Спасибо, Джабба

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

Ответы [ 4 ]

2 голосов
/ 17 декабря 2009

Написание этого более в стиле 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;
}
1 голос
/ 17 декабря 2009

Нет проблем в размещенном вами коде. Существует очень очевидная проблема с кодом real , с которым вы связаны: is_space и space являются функциями member , и их нельзя вызывать без экземпляра Split2. Это требование не имеет смысла, поэтому, по крайней мере, вы должны сделать эти функции статическими .

(На самом деле, для split_v3 не имеет особого смысла быть функцией-членом. Чего добиться, если класс Split2 достигнет наличия только свободной функции - возможно, в пространстве имен?)

1 голос
/ 17 декабря 2009

По запросу:

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 () вас смущает, и вы хотите больше узнать об использовании структур в качестве предикатов, вам следует взглянуть на перегрузку операторов и некоторые рекомендации для STL.

0 голосов
/ 17 декабря 2009

От руки, я бы сказал, что, вероятно, должно быть

i = str.find_if( ...
j = str.find_if( ...
...