Skip to content

Instantly share code, notes, and snippets.

@mburr
Last active December 12, 2015 00:08

Revisions

  1. mburr renamed this gist Jan 31, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. mburr created this gist Jan 31, 2013.
    88 changes: 88 additions & 0 deletions getline_until,cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,88 @@
    #include <functional>
    #include <iostream>
    #include <string>

    using namespace std;

    template <typename Predicate>
    istream& getline_until( istream& is, string& str, Predicate pred)
    {
    bool changed = false;
    istream::sentry k(is,true);

    if (bool(k)) {
    streambuf& rdbuf(*is.rdbuf());
    str.erase();

    istream::traits_type::int_type ch = rdbuf.sgetc(); // get next char, but don't move stream position
    for (;;ch = rdbuf.sgetc()) {
    if (istream::traits_type::eof() == ch) {
    is.setstate(ios_base::eofbit);
    break;
    }
    changed = true;
    rdbuf.sbumpc(); // move stream position to consume char
    if (pred(istream::traits_type::to_char_type(ch))) {
    break;
    }
    str.append(1,istream::traits_type::to_char_type(ch));
    if (str.size() == str.max_size()) {
    is.setstate(ios_base::failbit);
    break;
    }
    }

    if (!changed) {
    is.setstate(ios_base::failbit);
    }
    }

    return is;
    }

    // a couple of overloads (along with a predicate) that allow you
    // to pass in a string that contains a set of delimiter characters

    struct in_delim_set : unary_function<char,bool>
    {
    in_delim_set( char const* delim_set) : delims(delim_set) {};
    in_delim_set( string const& delim_set) : delims(delim_set) {};

    bool operator()(char ch) {
    return (delims.find(ch) != string::npos);
    };
    private:
    string delims;

    };

    istream& getline_until( istream& is, string& str, char const* delim_set)
    {
    return getline_until( is, str, in_delim_set(delim_set));
    }

    istream& getline_until( istream& is, string& str, string const& delim_set)
    {
    return getline_until( is, str, in_delim_set(delim_set));
    }

    // a simple example predicate functor
    struct is_digit : unary_function<char,bool>
    {
    public:
    bool operator()(char c) const {
    return ('0' <= c) && (c <= '9');
    }
    };


    int main(int argc, char* argv[]) {
    string test;

    // treat anything that's not a digit as end-of-line
    while (getline_until( cin, test, not1(is_digit()))) {
    cout << test << endl;
    }

    return 0;
    }