stream to integer and limit

Dear friends. How am i going to check if an input (integer in this case) by string stream exceeds the systems limits. I can inquire what this limit is by using - say numbMax:
 
  unsigned long numbMax = std::numeric_limits<unsigned long>::max();


Next i fixed to get the value trough the users command line input using string stream converting it to the input integer and check if it is truly an integer - let's call this integer numb1. And now i want to examine if it doesn't exceed the systems limit. But i have a problem, before comparing it i will have to give numb1 a value and it might get out of bounds while doing so.

Is there a smart solution instead of checking the length of the string and each character?

Streaming the input to declared integer is done by:
1
2
  inputNumber(&numb1, &numbMax);
  std::cout << numb1 << std::endl;

And the user input function is this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void inputNumber(unsigned long * numb, const unsigned long * numMax)
{
  std::string bufStr;
  bool tmpBool = true;
  do 
  {
    if (tmpBool) std::cout <<  "Enter the number smaller than " << *numMax << ": \n";
    else std::cout <<  "Oops, wrong input. Try again... " << ": \n";
    getline(std::cin, bufStr);
    tmpBool = false;
  }
  while(!checkIntInput(bufStr));
  std::stringstream(bufStr) >> *numb; //can cope trailing 0
}

To keep the set complete i give the function checkIntInput:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool checkIntInput(std::string & checkInt)
{
  bool rtrn = true; // return value
  if(checkInt.size() != 0)
  {
    char charInt;
    int intChar;
    for(std::size_t i = 0; i < checkInt.size(); ++i)
    {
      charInt = checkInt[i];
      intChar = int(charInt) - 48;
      //could add a break below, mhwa
      if((intChar + 1) > 0 && (intChar < 10)) rtrn = false;
    }
  }
  else rtrn = false;

Now passing the test the input will be string streamed to the actual integer (with its limits) and it should be compared with the integers limit - else: no go. But before this it can happen that the string stream represents a number to big to oblige the limit? And how should i make the program to participate in that? Again: without checking the characters in the input stream one by one.

Thank you for your help! Peter
You don't have to explicitly check that the input number is less than numeric_limits::max for that datatype. Rather if you check whether or not the data has been read successfully from std::cin that would automatically include a limits check, otherwise the data read would fail

How am i going to check if an input (integer in this case ...
yet your program shows unsigned long, so I'm not sure what datatype you really want but if it's int you're after you can use the following - it checks trailing and leading non digits, spaces etc:

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
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    bool fQuit = false;
    while (!fQuit)
    {
        std::cout << "Give me an integer ONLY\n";
        std::string choice;
        getline (std::cin, choice);
        std::stringstream stream(choice);
        int int_choice;
        if(!(stream>>int_choice) || stream.peek() != std::char_traits<int>::eof())
        {
            std::cout<<"Incorrect entry, try again\n";
        }
        else
        {
            std::cout << "Succes!!\n";
            fQuit = true;
            break;
        }
    }
}

Thank you very much gunnerfunner. Works like a charm. Please don't be offended, but i am asking myself: is C++ about logic or is it more ore less about memorizing an encyclopedia ;-) Everything that is smart seems to be hidden in classes. Should i go back to C?
is C++ about logic or is it more ore less about memorizing ...

my 2 cents is its about understanding the basics and lots of practice ... same as in every other walk of life really

Should i go back to C?

depends on what you want to do and where your interests lie; accordingly pick the language most suitable for your goals
Last edited on
@gunnerfunner,

I really like your solution. It's the best I have seen so far for that common topic. However I think could be even more useful in you put it in a function. Much easier to reuse.

1
2
3
4
5
6
7
8
9
10
11
bool isInt(const std::string& s)
{
  std::stringstream stream(s);
  int int_choice;
  if (!(stream >> int_choice) || stream.peek() != std::char_traits<int>::eof())
  {
    return false;
  }

  return true;
}
cheers Thomas
Topic archived. No new replies allowed.