By the way, to avoid duplicating all of this code every time, I once wrote a small template function to do this job:
template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result) { do { Os<<Prompt.c_str(); if(Is.fail()) { Is.clear(); Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } Is>>Result; if(Is.fail()) Os<<FailString.c_str(); } while(Is.fail()); } template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString) { InType temp; AcquireInput(Os,Is,Prompt,FailString,temp); return temp; }
The first overload may be preferable if you want to avoid copying, the second may be more convenient for built-in types. Examples of using:
//1st overload int AnInteger; AcquireInput(cout,cin,"Please insert an integer: ","Invalid value.\n",AnInteger); //2nd overload (more convenient, in this case) int AnInteger=AcquireInput(cout,cin, "Please insert an integer: ","Invalid value.\n");
source share