Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check that stream extraction has consumed all input?

In the following function, I try to see if a string s is convertible to type T by seeing if I can read a type T, and if the input is completely consumed afterwards. I want

template <class T>
bool can_be_converted_to(const std::string& s, T& t) 
{ 
  std::istringstream i(s);
  i>>std::boolalpha;
  i>>t;
  if (i and i.eof())
    return true;
  else
    return false;
}

However, can_be_converted_to<bool>("true") evaluates to false, because i.eof() is false at the end of the function.

This is correct, even though the function has read the entire string, because it hasn't attempted to read past the end of the string. (So, apparently this function works for int and double because istringstream reads past the end when reading these.)

So, assuming that I should indeed be checking (i and <input completely consumed>):

Q: How do I check that the input was completely consumed w/o using eof()?

like image 653
BenRI Avatar asked Nov 07 '12 16:11

BenRI


2 Answers

Use peek() or get() to check what's next in the stream:

return (i >> std::boolalpha >> t && i.peek() == EOF);

Your version doesn't work for integers, either. Consider this input: 123 45. It'll read 123 and report true, even though there are still some characters left in the stream.

like image 140
jrok Avatar answered Sep 30 '22 21:09

jrok


In many implementations of the standard library the eof will only be set after you tried reading beyond the end. You can verify that in your code by doing:

char _;
if (i && !(i >> _)) { // i is in a valid state, but
                      // reading a single extra char fails
like image 37
David Rodríguez - dribeas Avatar answered Sep 30 '22 22:09

David Rodríguez - dribeas