Floating point data unexpectedly succeeds on istream input into an integer

c++, double, int, templates

Solution

I'd try a slightly different take than you have. Specifically, I would not try to modify the error state of the input stream:

// Untested
template <class T> T clear_and_read(istream& inputstream) {
  std::string inputString;
  while(1) {
    try {

      // Grab one maximally-sized whitespace-delimited chunk of input
      inputstream >> inputString;

      // Note: lexical_cast throws if there are any extraneous characters.
      return boost::lexical_cast<T>(inputString);

    } catch (boost::bad_cast&) {
      std::cout << "\nPlease ensure you are inputting correct data type. Suggested data type: "<< typeid(input).name() <<".\n";
    }
  }
}

Note: If you don't have boost available in your compilation environment, `lexical_cast` is fairly trivial to implement yourself. If you get stuck, just ask for help.

References:

- http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast.html

EDIT Here is a fully tested version, that does not rely upon Boost.

#include <exception>
#include <sstream>
#include <string>
#include <iostream>
#include <typeinfo>

template <class T> T clear_and_read(std::istream& inputstream) {
  std::string inputString;
  while(inputstream) {
      // Grab one maximally-sized whitespace-delimited chunk of input
      inputstream >> inputString;
      std::istringstream itemstream(inputString);

      // Convert it:
      T t;
      itemstream >> t;

      // See if conversion worked and consumed everything
      if(itemstream && (itemstream.get() == EOF)) {
        // SUCCESS
        return t;
      }

      // oops
      std::cout << "\nPlease ensure you are inputting correct data type. Suggested data type: "<< typeid(T).name() <<".\n";
  }
  std::cout << "What to do with EOF?\n";
  return T();
}

int main () {
  clear_and_read<int>(std::cin);
  clear_and_read<double>(std::cin);
}

Problem

I'm writing a template function that will check if the user has assigned the correct type of data that the answer should be in. For example: ``` int main(){ int E; cout<<"Enter an integer: "<<endl; E = clear_and_read<int>(cin); cout<<E<<endl; } ``` where the function `clear_and_read` is defined as: ``` template <class T> T clear_and_read(istream& inputstream){ cin.sync();//removes anything still in cin stream cin.clear(); T input; inputstream>>input; while(inputstream.fail()){ cout<<endl<<"Please ensure you are inputting correct data type. Suggested data type: "<< typeid(input).name() <<"."<<endl; cin.sync(); cin.clear(); inputstream>>input; } return input; } ``` Now this works if I try to enter a `string` instead of an `integer`, but when I enter a `double` it just assigns it's first value. e.g. 5.678 becomes 5. What can I do inside the template function to flag if a `double` is being read into an `int`?

Original source