I’m trying to read in lines from a std::istream but the input may contain '\r' and/or '\n', so std::getline is no use.
Sorry to shout but this seems to need emphasis…
The input may contain either newline type or both.
Is there a standard way to do this? At the moment I’m trying
char c;
while (in >> c && '\n' != c && '\r' != c)
out .push_back (c);
…but this skips over whitespace. D’oh! std::noskipws — more fiddling required and now it’s misehaving.
Surely there must be a better way?!?
OK, here’s one way to do it. Basically I’ve made an implementation of
std::getlinewhich accepts a predicate instead of a character. This gets you 2/3’s of the way there:with a functor similar to this:
Now, the only thing left is to determine if you ended on a
'\r'or not…, if you did, then if the next character is a'\n', just consume it and ignore it.EDIT: So to put this all into a functional solution, here’s an example:
I’ve made a couple minor changes to my original example. The
Pred pparameter is now a reference so that the predicate can store some data (specifically the lastchartested). And likewise I made the predicateoperator()non-const so it can store that character.The in main, I have a string in a
std::stringstreamwhich has all 3 versions of line breaks. I use myutil::getline, and if the predicate object says that the lastcharwas a'\r', then Ipeek()ahead and ignore1character if it happens to be'\n'.