1

I am having trouble determining if an input is a letter or a number. If I enter anything it always says that it is not a number, what am I doing wrong. Here is my code:

#include <iostream>
#include <unistd.h>
#include <ctype.h>
  
using namespace std;
  
int main()
{
    int input = 0;
    
    cout << "Enter a number \n";
    cout << "input: ";
    cin >> input;
    if (isdigit(input)) {
        cout << "Your number is: " << input;
    }
    else { 
        cout << "This is not a number \n";
    }
    
    //wait for ten seconds
    usleep(10000000);
}
Peyman
  • 3,059
  • 1
  • 33
  • 68
  • Besides the fact that `cin >> input` is already only accepting integers and `isdigit` wants to work on characters ... what you really need to be doing is doing input a whole line at the time (using `std::getline`), then try to convert *that* to an integer. and see if succeeded with nothing following. – o11c Jul 29 '21 at 04:38
  • Since `input` is an `int` the expression `cin >> input;` will only read integers. If you want to read anything and then decide what it is you'll need to use a string. – Retired Ninja Jul 29 '21 at 04:38
  • `isdigit` expects a character value (despite the fact that its input parameter is `int`). What you're doing here is reading an integer and then trying to treat that as a character. To begin with, that's completely incorrect. And furthermore, it's not possible to read anything that _isn't_ a number. What will happen is `cin` will enter an error state. – paddy Jul 29 '21 at 04:39

2 Answers2

0

Since isdigit() expects an ASCII value as its argument, it will return true only if you type in a number between 48 (aka the ASCII code for "0") and 57 (aka the ASCII code for "9"), which isn't what you want.

In order to get the behavior you want, you'll need to read the user's input into a string, and then analyze the contents of the string to see if they reasonably represent an integer or not. Something like this:

#include <iostream>
#include <string>
#include <unistd.h>
#include <ctype.h>

using namespace std;

int main()
{
    string inputStr;

    cout << "Enter a number \n";
    cout << "input: ";
    cin >> inputStr;

    // Assume a string counts as representing an integer
    // if the first character of the string is an ASCII digit.
    // (You might also want to accept strings where the
    // first character is a + or - symbol and is immediately
    // followed by an ASCII digit, but for simplicity I'm
    // omitting that logic here)

    if ((inputStr.length()>0)&&((isdigit(inputStr[0])))) {
       int number = stoi(inputStr);
       cout << "Your number is: " << number << endl;
    }
    else {
       cout << "[" << inputStr << "] is not a number" << endl;
    }

    //wait for ten seconds
    usleep(10000000);
}
Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Maybe point out that `std::stoi` will throw an exception on non-numeric data. – PaulMcKenzie Jul 29 '21 at 04:57
  • Oddly, it doesn't when I try it (e.g. if I enter 123foobar, `std::stoi()` just returns 123). I think non-numeric data after numeric data is quietly ignored. – Jeremy Friesner Jul 29 '21 at 05:13
  • Do we need to handle overflow here? – prehistoricpenguin Jul 29 '21 at 06:18
  • `std::isdigit` does **not** "expect an ASCII value as its argument". It takes a value of type `char` (or the value `EOF`) and returns non-zero if that value represents a digit in **in the compile-time character encoding**. That is often ASCII, but ASCII is not required. Some systems do not use ASCII, and `std::isdigit` works just fine on them. – Pete Becker Jul 29 '21 at 13:52
  • @PeteBecker all true, but I didn't want to get into that level of nuance when answering a beginner's programming question. – Jeremy Friesner Jul 29 '21 at 14:35
0

Agree on Jeremy, I would like to add https://stackoverflow.com/a/5655685/7637661 for reference.

TLDR

#include <iostream>
  
using namespace std;

int main() {
  int input = 0;
  cout << "Enter a number \n";
  cout << "input: ";
  cin >> input;
  if(!cin) // or if(cin.fail())
  {
    // user didn't input a number
    cin.clear(); // reset failbit
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //skip bad input
    // next, request user reinput
    cout << "This is not a number " << endl;
  }

  cout << "Your number is: " << input;
}