1

I want the code to check input in command line is integer. i.e. 10b is not valid. I tried isdigit() but is not working? Thanks in advance.

#include <cs50.h>
#include <stdio.h>
#include <ctype.h>

int main(int argc, string argv[])
{
   if (argc == 2)
   {
       int key = atoi(argv[1]);

       if (isdigit(key))
       {
          printf("Success\n\%i\n", key);
          exit(0);
       }

    }
  printf("Usage: ./caesar key\n");
  return 1;
}
3
  • 3
    I suggest strtol which sets a pointer you supply to point to the character that stopped the conversion. Commented Feb 10, 2019 at 23:15
  • atoi does no error checking. And the correct declaration is int main(int argc, char *argv[]); the <cs50.h> header's definition typedef char *string; is a really bad idea. (A pointer is not a string.) Commented Feb 11, 2019 at 0:09
  • Do you consider "1234567890123456789012345678901234567890" an integer. Math-wise it is, but certainly will not fit in an int or common long long. Commented Feb 11, 2019 at 0:44

3 Answers 3

1

Function isDigit checks if a single character is a digit, i.e. in the range between '0'..'9'. To check if a string is a number, I'd suggest to use function strtol.

long strtol(const char *str, char **str_end, int base ) converts a string str to an integral number and also sets the pointer str_end to the first character that took not part in the conversion any more. If you require that no characters must follow your number, then str_end must point to the string's end, i.e. to string termination character '\0':

#include <stdio.h>
#include <stdlib.h>

int isNumber(const char* str) {

    if (!str || *str=='\0') {  // NULL str or empty str: not a number
        return 0;
    }

    char* endOfNum;
    strtol(str,&endOfNum,10);

    if (*endOfNum == '\0') { // string is at its end; everything in it was a valid part of the number
        return 1;
    } else {
        return 0;  // something that is not part of a number followed.
    }

}

int main() {
    const char* vals[] = {
        "10b",
        "-123",
        "134 ",
        "   345",
        "",
        NULL
    };

    for (int i=0; vals[i]; i++) {
        printf("testing '%s': %d\n", vals[i], isNumber(vals[i]));
    }
}

Output:

testing '10b': 0
testing '-123': 1
testing '134 ': 0
testing '   345': 1
testing '': 0

Adapt the meaning of corner cases like empty strings or NULL-strings to your needs.

Sign up to request clarification or add additional context in comments.

Comments

0

The isdigit function checks whether a single character represents a single digit. (numbers − 0 1 2 3 4 5 6 7 8 9).

In order to check if a string is an integer you could use a function like that. It will

bool isNumber(char number[])
{
    int i = 0;
    // only if you need to handle negative numbers 
    if (number[0] == '-')
        i = 1;
    for (; number[i] != 0; i++)
    {
        if (!isdigit(number[i]))
            return false;
    }
    return true;
}

1 Comment

2 ideas: Allow a leading '+' and use isdigit((unsigned char) number[i]) for correct functionality when number[i] < 0.
0

My first thought would be to use something like:

int inputvalue = 0;
if (sscanf(argv[i], "%d", &inputvalue) == 1)
{
    // it's ok....
}
else
{
    // not an integer!
}

or something like that. See http://www.cplusplus.com/reference/cstdio/sscanf/

4 Comments

That does not pick up on the invalid 'b' mentioned in the question.
Fair point. I guess it could be extended to do the sscanf, then sprintf the returned value into a string and use strlen or strcmp to check the input string and the result string are the same / same length. e.g. if (sscanf(argv[i], "%d", &inputvalue) == 1) { char compare[strlen(argv[i]) + 1]; sprintf(compare, "%d", inputvalue); return strcmp(compare, argv[i]) == 0; } depends on how clear/efficient you want to be,
sscanf has undefined behavior on numeric overflow. If the input is 999999999999999999999999999, anything can happen.
Then, I guess, you could just check the length of the argument and, if it's too long to be a sensible value, tell your user not to be so stupid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.