Last active
December 12, 2015 00:08
-
-
Save mburr/4681009 to your computer and use it in GitHub Desktop.
getline_until = #mburr
A version of getline() that takes a predicate to determine the delimiter. Some overloads provided that take a list of characters as delimiters (like strtok()) From an SO answer: http://stackoverflow.com/a/9273019/12711
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment