-1

I'm simulating a calculator and would like to know how do I take just positive inputs and no other characters (negative integer, alphabets etc.)

I've tried using 2 do while loops, one validating positive integer and another validating characters, but it seems like there cant be 2 loops for 1 input, if not it will look weird...

do{

 if (invalid == true)
 {
    cout << "Invalid input, please enter a positive number" << endl;
 }
 cout << "Please enter the first number:" << endl;
 cin >> num1;
 cin.ignore();
 invalid = true;
 } while (num1 < 0);
 invalid = false;

With the code above it only validates the input to be positive integer, but once I input characters such as alphabets, the program crashes. Is there any way to exclude both at the same time?

  • Generally in those cases you want to read a `string`, not a numeric value like an `int` or `double` and see whether it matches a specific number pattern. You may be interested in `regex`. – Fureeish Apr 02 '19 at 12:21
  • 2
    Possible duplicate of [How to check if the input is a valid integer without any other chars?](https://stackoverflow.com/questions/20287186/how-to-check-if-the-input-is-a-valid-integer-without-any-other-chars) – skratchi.at Apr 02 '19 at 12:21

2 Answers2

1

My recommendation is to read the full line as a string (with std::getline) and then attempt to parse the string as an unsigned integer.

It could be implemented something like

unsigned value;

for (;;)
{
    std::string input;
    if (!std::getline(std::cin, input))
    {
        // Error reading input, possibly end-of-file
        // This is usually considered a fatal error
        exit(EXIT_FAILURE);
    }

    // Now parse the string into an unsigned integer
    if (std::istringstream(input) >> value)
    {
        // All went okay, we now have an unsigned integer in the variable value
        break;  // Break out of the loop
    }

    // Could not parse the input
    // TODO: Print error message and ask for input again

    // Loop continues, reading input again...
}

This could be put into a function to generalize it, and so it can be reused for getting multiple values. You could even make the function a template, so it can be used for different input types (signed or unsigned integers, floating point, even objects with a suitable input operator >> overload).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Check std::cin >> result and when an error occurs clear the error then read a word (you can also read all the line if you prefer), do not forget to manage the EOF case.

For instance

#include <iostream>
#include <string>

int main()
{
  int n;

  for (;;) {
    if (!(std::cin >> n)) {      
      // remove bad 'word'
      std::cin.clear();
      std::string s;

      if (!(std::cin >> s)) {
        std::cerr << "EOF" << std::endl;
        return -1;
      }
      std::cerr << "not a number" << std::endl;
    }
    else if (n < 0)
      std::cerr << "negative value" << std::endl;
    else
      break;
  }

  std::cout << "positive value " << n << std::endl;

  return 0;
}

Compilation and execution :

pi@raspberrypi:~ $ g++ -pedantic -Wall -Wextra i.cc
pi@raspberrypi:~ $ ./a.out
aze
not a number
-1
negative value
2
positive value 2
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ echo | ./a.out
EOF
pi@raspberrypi:~ $ ./a.out
aze -1 23
not a number
negative value
positive value 23
bruno
  • 32,421
  • 7
  • 25
  • 37