I have a problem with reading an integer from a user. What I do now is using this bit of code to read an input:
1 2 3 4 5 6 7 8
int intInput
while(!(cin >> intInput))
{
printString("Not a valid input! Try again: ");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
But my problem is now that when a user inputs 4jlkjl, it get a valid input cause of the leading number. How do I make such a input to generates an error? I've looked a little at stringstream but haven't figgered out something good yet. Anyone got any ideas?
getString() does getline(cin, stringInput) and returns the string.
But this doesn't work either, when I type a leading number it converts to a correct input, which is bad. Besides when I enter a correct number I have to enter an extra "enter" to make it count.
while(!convertOK)
{
stringstream convert(getString()); //Reads the input
if(convert >> intInput) //Try to convert to a number
{
string leftovers;
getline(convert,leftovers); //Reads the rest from the input
if(leftovers == "") //If leftovers is empty, we have a correct number
{
convertOK = true;
}else{
printString("Not a valid input! Try again: ");
}
}else{
printString("Not a valid input! Try again: ");
}
}
#include <iostream>
#include <sstream>
#include <string>
usingnamespace std;
//----------------------------------------------------------------------------
template <typename T>
struct input_t
{
mutable T& n;
explicit input_t( T& n ): n( n ) { }
input_t( const input_t <T> & i ): n( i.n ) { }
};
//----------------------------------------------------------------------------
template <typename T>
inline
input_t <T>
input( T& n )
{
input_t <T> result( n );
return result;
}
//----------------------------------------------------------------------------
template <typename T>
istream& operator >> ( istream& ins, const input_t <T> & i )
{
// Read a line (terminated by ENTER|NEWLINE) from the user
string s;
getline( ins, s );
// Get rid of any trailing whitespace
s.erase( s.find_last_not_of( " \f\n\r\t\v" ) + 1 );
// Read it into the target type
istringstream ss( s );
ss >> i.n;
// Check to see that there is nothing left over
if (!ss.eof())
ins.setstate( ios::failbit );
return ins;
}
//----------------------------------------------------------------------------
int main()
{
int n;
cout << "Please enter an integer> " << flush;
cin >> input( n );
while (!cin)
{
cin.clear();
cout << "Please, enter only an INTEGER> " << flush;
cin >> input( n );
}
cout << "Good job!\n""You entered the number " << n << endl;
return 0;
}
The interesting part of this piece of code is that the operator >> overload takes a const input_t... so that it can work with object temporaries returned by the input() named template constructor.
Keep in mind that lines 53 and 58 could have been combined into the while condition, but I kept them separate for clarity.