ccommand-line-interfacecs50

how to check if a string is a number with a built-in Library?


I tried using the isdigit function but it only works for chars. I know I can write a function that'll check every char in a string but is there an already built-in way in c

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

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./caesar key");
        return 1;
    }
    else if (isdigit(argv[1]) != 1)
    {
        printf("Usage: ./caesar key");
        return 1;
    }
}

Solution

  • You cannot use isdigit() to way you do in the question: its argument must be a single character (all values of type unsigned char) or the special negative value EOF. Passing a string has undefined behavior.

    Your question has many possible answers, depending on what you mean by if a string is a number:

    Here is an alternative using no library function correctly:

    #include <cs50.h>
    #include <limits.h>
    #include <stdio.h>
    
    enum key_result {
       KEY_OK,          // string is a valid integer
       KEY_TOO_LARGE,   // value is outside the range of type `int`
       KEY_EMPTY,       // string is empty
       KEY_NOT_NUMBER,  // string does not contain only digits
    };
    
    /* parse the argument as a key, store value into `*dest` */
    enum key_result get_key(const char *s, int *dest) {
        enum key_result res;
        int value;
    
        // string must not be empty
        if (*s == '\0')
            return KEY_EMPTY;
    
        value = 0;
        res = KEY_OK;
        // consume digits
        while (*s >= '0' && *s <= '9') {
            int digit = *s++ - '0';
            if ((value > INT_MAX / 10)
            ||  (value == INT_MAX / 10 && digit > INT_MAX % 10)) {
                value = INT_MAX;
                res = KEY_TOO_LARGE;
            } else {
                value = value * 10 + digit;
            }
        }
        if (*s != '\0')
            return KEY_NOT_NUMBER;
    
        *dest = value;
        return res;
    }
    
    int main(int argc, char *argv[]) {
        int key = 0;
    
        if (argc != 2) {
            fprintf(stderr, "Usage: ./caesar key\n");
            return 2;
        }
        switch (get_key(argv[1], &key)) {
          case KEY_OK:
            printf("caesar: key is %d\n", key);
            break;
          case KEY_TOO_LARGE:
            fprintf(stderr, "caesar: key value is too large: '%s'\n", argv[1]);
            return 1;
          default:
            fprintf(stderr, "caesar: key must be a number\n");
            return 1;
        }
        //...
    }