Preventing a user from entering too large an integer

I have a program that takes a users input for an int (in this case to use as a grid reference) and I wish it to only take valid numbers, and ignore letters. At the moment the program catches too high or low values, and prevents invalid characters from being used, however if a user enters a number with too many digits the entire program crashes.
Why is this? And what would be the simplest way to prevent it?

Error Checking Code:
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
bool Player::checkPlayerStartInput(int nPlayerInput, char cCoord)
{
     if(cCoord == 'x')
     {
               if(nPlayerInput < 1 || nPlayerInput > nMatrixSizeX)
               {
                               return false;
               }
               else
               {
                   return true;
               }
     }
     else if(cCoord == 'y')
     {
               if(nPlayerInput < 1 || nPlayerInput > nMatrixSizeY)
               {
                               return false;
               }
               else
               {
                   return true;
               }
     }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int getXInput()
{
    char cTempInput[25];
    int nReturnVar;
    bool bInputOK = true;
    
    do{
       cout << "X: ";
       while(!(cin >> cTempInput))
       {
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "Invalid input.  Try again: ";
       }
    }while(bInputOK != true);
    
    stringstream convert(cTempInput);
    if(!(convert >> nReturnVar))
    {
                 nReturnVar = 0;
    }

    return nReturnVar;
}
Instead of reading into a limited C-style char array of size 25, try reading into an std::string.
A short answer, change cin >> cTempInput to cin.get(cTempInput, 24, ' ')

Long answer:

Your do/while statement is worthless, as bInputOK is true and never set to not true. The while statement doesn't do anything because you can't fail a character input. You need another cin.ignore() at line 16 because if line 9 didn't compute to true then you could still have characters in your buffer.

Another shortcoming here is that you don't know if the input failed or if the person really typed zero.



Last edited on
Thanks, I change the way I do the coding in it quite a lot to try out different stuff and the do/while was a remnant I'd forgotten was there from a previous iteration of the program :)
Just one question, what do you mean about knowing if the input failed? I admit I haven't really understood about io buffers / streams and the like, I looked into them but didn't quite understand how they were implemented
making the >> operator extract a non-integer when it was expecting an integer sets the istream (cin, ifstream) object's fail bit. Hence the line:
if (!(cin >> integer)). This would be the same for any number data type that you enter a non-number.

The function that would ensure a entry was a number would be this:
1
2
3
4
5
6
7
8
9
10
11
12
13
double getNum()
{
  double num;
  while (!(cin >> num)
  {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "Invalid input.  Try again: ";
  }
  // However, if the first input didn't trigger the while loop, there is still at least a '\n' in the buffer
  cin.ignore(numeric_limits<streamsize>::max(), '\n');
  return num;
}


You could also do the char array to stringstream to int method. In this case, it might look something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
int getXInput()
{
  char cTempInput[25];
  int nReturnVar;
  do 
  {
    cin.get(cTempInput, 24, ' ');  // read until 24 chars read or a space (third argument defaults to '\n')
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    stringstream convert(cTempInput);
  }
  while (!convert >> nReturnVar);
  return nReturnVar;
}


So getNum() returns something that is surely a double, but maybe we want to ensure an integer:
1
2
3
4
5
6
7
8
9
10
int getInt()
{
  double num = getNum();  // getNum has protected against a failed cin
  while (static_cast<int>(num) != num)
  {
    cout << "Integers only.  Try Again: ";
    num = getNum();
  }
  return static_cast<int>(num);
}


Then proceed to getIntInRange:

1
2
3
4
5
6
7
8
9
10
11
int getIntInRange(const int& low, const int& high)
{
  int num = getInt();
  while (num < low || num > high)
  {
    cout << "Number must be >= " << low 
         << " and <=  " << high << ".  Try again: ";
    num = getInt();  // Thanks EssGeEich!
  }
  return num;
}
Last edited on
num = getInt;
Little mistake! Should be: num = getInt();
Thanks for the help :) That's really cleared some of my questions up!
Topic archived. No new replies allowed.