0

My code's aim is to take in 2 command line arguments (inclusive of programme name), and to print out responses as shown based on the given 2nd command line argument. If the command line argument is an integer, the user's input is accepted or "Success"and if it as anything else (e.g. a string or more than one command line argument), it will be Null and the error message will be shown. This is for CS50 caesar for those who are familiar

My Code is as follows:

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

int main(int argc,string argv[])
{
 
    char *x = argv[1];
    if (argc == 2 && isdigit(x))
    {
        printf("Success\n");
    }
    else
    {
        printf("Usage: ./caesar key\n");
    }
    
}

The code compiles but I am given a segmentation fault. I am aware segmentation fault is the programme trying to access something outside of the allocated memory for the array (correct me if I am wrong) but I did specify argv[1].

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Read [isdigit manual](https://linux.die.net/man/3/isdigit). What arg type does it need and what did you give it? – kaylum Jul 18 '20 at 05:56
  • If no argument is given, then `argv[1]` doesn't exist – Jorengarenar Jul 18 '20 at 05:57
  • And to answer the question in the title - using a debugger is one common way to debug code (for seg faults and many other types of code issues). – kaylum Jul 18 '20 at 05:57
  • You are telling `isdigit` to access something not-a-digit (and not an `unsigned char`). `isdigit(*x)` would make much more sense. Which technically should be `isdigit((unsigned char)*x)` – David C. Rankin Jul 18 '20 at 06:12

1 Answers1

1

The isdigit takes as an argument, an int, that contains a character code as an unsigned character.

Unfortunately isdigit is often implemented as a macro, and written in such a way that you do not get a warning if you pass in the wrong kind of data. You're passing in a pointer to a character, which is not a single character. The first character of the first command line argument is x[0]. However this must be converted to unsigned char.

Therefore these are wrong

  • isdigit(x)

  • isdigit(x[0])

What you could use to check if the first character of the first argument is a digit is

isdigit((unsigned char)x[0]))

but in the end what you want is not to check if any of these are digits, but to convert the string to an integer, and see if an error occurs - use strto(u)l for x and see if it succeeded; then check the range of the resulting value.