#include #include #include using namespace std; template 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 { 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 { 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; }