-1
int num = 0;
 
while(true){
  cout << "enter num: ";
  cin >> num;
  if(!(num)){
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "num must be an int" << endl;
  }else if(num <= 0){
    cout << "num must be greater than 0" << endl;
  }else if(static_cast<double>(static_cast<int>(num)) != num){
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "num must be an int" << endl;
  }else{
    break;
  };
};

I've been looking through SO and I found some threads that addressed similar issues, but nothing that is specific to what I'm trying to achieve. I'm only trying to accept integer inputs, no decimals, no strings, no characters. If I enter in a negative number or 0, it'll throw me an error saying "num must be greater than 0." If I enter in a, it'll throw me an error saying "num must be an int." If I enter 1.0, it'll throw me an error saying "num must be an int."

The problems I'm running into with this is when I enter in 0 for example, instead of executing the conditional statement that checks (num <= 0), it runs the conditional statement that says (!(num)). The other problem I'm running into is when I enter in a value that has a decimal, like 2.0, it'll truncate the numbers after the decimal and send in 2 as the value, completely glossing over the check to see if it's a decimal value and telling the program that it's a valid integer when it's not.

Does anyone have a solution for this, or an article link that solves problem like mines? Thank you!

space
  • 3
  • 1
  • 1
    what do you expect `if(!(num))` to do? it is the same as `if (num == 0)`. `num` is always an `int`, it cannot be something else, no matter what the user enters, because you declared it to be an `int` – 463035818_is_not_an_ai Feb 07 '22 at 20:12
  • Unrelated note: Thinking about Stack Overflow as consisting of Threads can lead to misusing Stack Overflow. Rather than thread, think of them as a Question and zero or more Answers. – user4581301 Feb 07 '22 at 20:12
  • `static_cast(num)` is also not doing anything useful – 463035818_is_not_an_ai Feb 07 '22 at 20:14

1 Answers1

1

This:

cin >> num;
if(!(num))

Should be this:

if (!(cin >> num))

You are checking the value of num when you should instead be checking the error state of cin. operator>> returns a reference to the input stream, which is then implicitly convertible to bool, where false means the stream encountered an error.

Also, this is completely useless:

else if(static_cast<double>(static_cast<int>(num)) != num)

Casting an int value to an int is a no-op, and casting an int value to a double back to an int will get you the original int value.

num is an int, it can't read in anything else. So, by the time your code reaches this point, you know num must be holding a valid int value. However, if the user had actually entered a floating-point number instead, operator>> would have stopped reading at the decimal point, leaving it and the remaining fractional value in cin's input buffer for later reading.

Also, the 2nd call to cin.ignore() is wrong. By that point, operator>> was able to read in an int value, it just wasn't satisfactory to you. So don't ignore subsequent input yet.

If you really need to differentiate between integer and floating-point input, you will have to read in the input as a string first, and then parse it to see what it actually holds, eg:

int num = 0;
string s;
size_t pos;
 
while (true){
  cout << "enter num: ";
  if (!(cin >> s)){
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "input error, try again" << endl;
  }
  else{
    try{
      num = stoi(s, &pos);
      if (pos != s.size()) throw invalid_argument("");
      if (num > 0){
        break;
      }
      cout << "num must be greater than 0" << endl;
    }
    catch (const exception &){
      cout << "num must be an int" << endl;
    }
  }
}

Online Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • That worked, except it created a new problem. When I ran the file, it asked me for my input. I put in ```0``` and then my terminal was just whitespace. I typed in ```0``` again, and then it updated with the print statements saying "it must be greater than 0." I tried it again with doing ```1``` (an acceptable integer), and it showed me whitespace again until I typed in ```1``` again and then it exited out of the loop – space Feb 07 '22 at 20:22
  • @space [works fine for me](https://ideone.com/KyMWXd) – Remy Lebeau Feb 07 '22 at 20:42
  • that issue was arising before I updated the code to the new version you sent me to look at it. I'm still running the version that has the switch to ```if (!(cin >> num))``` and I'm getting these whitespace issues. I'm assuming you aren't getting them with updated code snippets you sent above? – space Feb 07 '22 at 20:56
  • @space [cant reproduce](https://ideone.com/yuRH0o) with just that one change alone. But, if that is the only change you are making, then it is not enough. The 2nd call to `cin.ignore()` when a valid `int` is read needs to be removed, too. But I doubt that is the cause of your issue. You are just going to have to [debug your code](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) to figure out what is really happening. – Remy Lebeau Feb 07 '22 at 21:05