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()?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With