# Thread: Only Accepting Ints and Doubles

1. ## Only Accepting Ints and Doubles

I am writing a code that will only allow integers between a minimum and maximum value. However, I'm having trouble limiting the user to just integers. Here's what I have so far. The commented part is where I'm having trouble.

Code:
```  int GetInteger(const int& min, const int& max) {
int input;
const std::string invalid_int_("Failure: No integer found.");
const std::string low_int_("Failure: Integer is below minimum value.");
const std::string high_int_("Failure: Integer is above maximum value.");
if (/*needs to only accept numbers*/) {
if (input < min) {
std::cout << low_int_ << endl;
input = 0;
} else if (input > max) {
std::cout << high_int_ << endl;
input = 0;
}
} else {
std::cout <<invalid_int_ << endl;
input = 0;
}
return input;
}```
To clarify, I can't do something like this
Code:
`if(x <= 9999999 && x > 0)`
This would be problematic if the user set the max to something even higher. I need to accept all numbers. Only after that can I start limiting them to be between the min and the max.

I am also making a nearly identical function, except in this case it would only allow doubles. Can someone please explain to me how to do this? Thank you.

Note: I do not need to accept scientific notation for doubles.

2. You could start by using some of the functionality of std::numeric_limits. But if you're using any integer type you will never be able to accept all numbers.

Jim

3. Well let's see if I got this right...so if I DID make the parameters of this function -2147483648 and 2147483647, I would be allowing all possible integers in the C++ language, yes?

4. Originally Posted by Erik Ingvoldsen
I would be allowing all possible integers in the C++ language, yes?
I don't believe the standard says the limits of types or their sizes, so that would be a no. But popular implementations have 64-bit types, so the ranges would be higher than that.

Anyway, as far as your problem goes, you should read the input into a string and then parse it to find the real type of the input the user entered (i.e. be it a floating point or integer).

5. I'm sorry, but I've never heard of the term "parse". What does that mean? How would I implement it?

6. Not necessarily an int could hold larger values or those values could be too large. Remember the ranges of the integral types are implementation defined and those values are much larger than the value that an int must be able to accommodate for standard conformance. That is why I suggested you look into the numeric_limits class. By using this class you can determine the minimum and maximum values your integers can accommodate.

Jim

7. One approach is to use std::cin >> input and check the return value, which is precisely what you would do if you placed that as the condition of the if statement.

8. Hmmm...well I was going to use getline on the main method when I tested this out. What's the difference between the two?

9. Hmmm...well I was going to use getline on the main method when I tested this out. What's the difference between the two?
O_o

You can use whatever you want to get the input from the user.

The point laserlight was making is that you can validate that the input is actually an integer.

In your case, you could `getline' a string before throwing the input into `std::istringstream' which you could then use to try and pull out an integer.

Soma

10. Originally Posted by phantomotap
before throwing the input into `std::istringstream' which you could then use to try and pull out an integer.
This is where I'm getting confused. Do you think you could show me an example?

11. Are you compiling with respect to C++11? If so, there's also std::stoi, which you can call after calling std::getline. If not, it could be something along these lines:
Code:
```int result;
std::string line;
if (getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> result && ss.eof())
{
// Valid input stored in result
// though another check is needed if the desired range is smaller than the range of int
}
else
{
// Report an input error
}
}```
ss.eof() is used to ensure that there isn't say, a stray alphabetic letter after the integer portion of the line.

12. OK, I tried to implement what you put down, as well as make some other changes when I realized the project didn't give me any input values for the parameters. It's compiling just fine, but there's a problem with the test. This is my current code:

Code:
```class UserInputHandler {
public:
int GetInteger(int min, int max) {
const std::string invalid_int_("Failure: No integer found.");
const std::string low_int_("Failure: Integer is below minimum value.");
const std::string high_int_("Failure: Integer is above maximum value.");
int result;
min = 0;
max = 100;
std::string line;
std::cin >> line;
if (getline(std::cin, line)) {
std::stringstream ss(line);
if (ss >> result && ss.eof()) {
if (result < min) {
std::cout << low_int_ << endl;
result = 0;
} else if (result > max) {
std::cout << high_int_ << endl;
result = 0;
}
} else {
std::cout <<invalid_int_ << endl;
result = 0;
}
}
std::cout << "Integer Entered is: " << result << endl;
return result;
}
};

int main() {
UserInputHandler handler;
handler.GetInteger(0,100);
}```
But when I test it, it tells me my integer is not an integer.

Code:
```\$ ./test
2
Failure: No integer found.
Integer Entered is: 0```

13. I noticed that you have this line still in your code even though you are calling getline:
Code:
`std::cin >> line;`
Remember to #include <sstream> for std::stringstream. It may have been included indirectly, but you should not rely on that.

14. You're also not using the parameters since one of the first things you do is reassign them to constant values:

Code:
``` int GetInteger(int min, int max) {

...
min = 0;
max = 100;```
One other note look at this snippet:

Code:
`          std::cout << high_int_ << endl;`
You're properly scoping std::cout but fail to properly scope std::endl;

You should be including several headers in this file, <iostream>, <string> and <sstream> don't rely on some "magic" to include the required include files always include the required files.

Jim

15. Oops, added those values in and I forgot to take them out. And yeah, everything's included. I put it all in beforehand just in case I ever need it. Anyway, I updated the code but there's a small problem with the test:

Code:
```class UserInputHandler {
public:
int GetInteger(const int& min, const int& max) {
const std::string invalid_int_("Failure: No integer found.");
const std::string low_int_("Failure: Integer is below minimum value.");
const std::string high_int_("Failure: Integer is above maximum value.");
int result;
std::string line;
std::getline(std::cin, line);
if (getline(std::cin, line)) {
std::stringstream ss(line);
if (ss >> result && ss.eof()) {
if (result < min) {
std::cout << low_int_ << endl;
result = 0;
} else if (result > max) {
std::cout << high_int_ << endl;
result = 0;
}
} else {
std::cout <<invalid_int_ << endl;
result = 0;
}
}
std::cout << "Integer Entered is: " << result << endl;
return result;
}
};

int main() {
UserInputHandler handler;
handler.GetInteger(0,100);
}```
The test, however, asks me to input two things for some reason.

Code:
```\$ ./test
1
2
Integer Entered is: 2```
I admit, I should have asked you from the start what these if statements were doing exactly but I was stressing over other problems with the code. But it's better that I understand what's going on, so I'd also like to ask what's happening here.

Code:
```if (getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> result && ss.eof())
{```