Wouldn't it be nice if all that error checking was encapsulated into a function that just returned true or false based on whether the input succeeded or failed? Heck, it would be great if that function worked with strings, too, or even wide character streams. Wait, it's already been done:
Code:
#include <iostream>
#include "basic_input.h"
int main()
{
int value = 0;
// Prompt.
while (!jlou::basic_input(std::cin, value))
{
// Error message.
// Re-prompt.
}
}
Here is the basic implementation for non-string types.
Code:
namespace jlou
{
template<typename charT, typename traits>
inline std::basic_istream<charT,traits>& ignore_line(std::basic_istream<charT,traits>& is, charT delim)
{
return is.ignore(std::numeric_limits<std::streamsize>::max(), delim);
}
template<typename charT, typename traits, typename T>
inline bool basic_input(std::basic_istream<charT,traits>& is, T& x, charT delim)
{
std::ios::fmtflags old_flags = is.flags();
if ((is >> std::noskipws >> x) && (is.eof() || is.get() == delim))
{
is.flags(old_flags);
return true;
}
is.flags(old_flags);
x = T();
is.clear();
ignore_line(is, delim);
return false;
}
}
The full definition that handles C and C++ strings is in the small attached file. My old version worked on VC++ 6, but this one doesn't yet (if you'd like that version just ask).
If you use this and can give it input that causes an infinte loop or unexpected behavior, or leaves cin in an incorrect state following the input, let me know, although I think I'm close to catching all potential errors.