Reading an integer

Hi,

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?

Thanks
/Christian
Last edited on
Hmm, that was something that I tried aswell.

1
2
3
4
5
6
7
8
9
10
while(true)
{
	stringstream convert(getString());
		
	if(convert >> intInput)
		break;

	printString("No int");

}


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.
Hi again, I think I solved it using this bit of code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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: ");
			}
		
		}


Just to let you know.
Here's something to blow your mind. :-]

The template stuff you can ignore if you like... the important part is checking istream::eof() on line 40.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <sstream>
#include <string>
using namespace 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.

Have fun!
Topic archived. No new replies allowed.