andy
andy

Reputation: 391

segmentation fault checking user arguments c

I am trying to validate user input from the command line with argc and argv but am running into a segmentation fault and am not sure why.

I want to validate the user has entered a positive int (so argc =2 and argv is positive).

Here is my code:

int main (int argc, string argv[])
{
    int k = atoi(argv[1]);
    if (argc != 2 && k <1)
    {
          return 1;
    }
}

The k < 1 part of my code seems to be working fine, but I get segmentation errors every time I try to run without the program name and an argument (agrc !=2).

EDIT:

More clear description of the error handling problem:

If I run ./myprogram -2 then I get my return 1 as expected.

If I run ./myprogram hjdksfhdsk then I get my return 1 as expected.

If I run ./myprogram then I get a segmentation fault.

It is this behaviour that makes me think my handling of the argc value is at fault, but I am not sure why I cannot just test argc !=2.

Upvotes: 0

Views: 1861

Answers (3)

This is incorrect, since in C string is not a built-in type (and is not a standard type defined in some standard header - notice that C++ has std::string defined in its <string> standard header).

The signature of main has to be

int main(int argc, char**argv);

The convention is that argv[argc] is the null pointer, and the argc pointers from argv[0] to argv[argc-1] are non-null pointers to null-terminated strings.

Notice that (at least on Linux and Posix systems) program arguments are not user input to the program. The shell has been given a command line as input and has expanded that command line into program arguments. Your program could later read some input, e.g. with scanf.

You cannot convert a NULL pointer with atoi, so you should check argc before doing the conversion.

int main(int argc, char**argv) {
   if (argc!=2) { 
      fprintf(stderr, "%s needs two arguments\n", argv[0]);
      exit(EXIT_FAILURE);
   };
   int k = atoi(argv[1]);
   if (k<=0) {
      fprintf(stderr,
              "%s wants a positive first argument, but got %s\n",
              argv[1]);
      exit(EXIT_FAILURE);
   }
   // now do the real thing
 }

BTW, I believe that (at least on Linux or Posix system) a program should accept the --help argument per the GNU coding standard. I suggest you to use getopt (notably getopt_long) or argp to parse program arguments.

At last, compile with all warnings and debug information (e.g. with gcc -Wall -g) and learn how to use the debugger (e.g. gdb).

Upvotes: 5

Craig Taylor
Craig Taylor

Reputation: 1939

As others have noted string is not a base type. However since you are getting results in one case your segmentation fault has to do with the atoi on argv 1. In c arrays are 0 based so you're trying to convert uninitialized memory. Use the argc test before the atoi.

Upvotes: 0

Ed Heal
Ed Heal

Reputation: 60037

Your main should be

int main(int argc, char*argv[])

And do the check before using on atoi on argv[1]

Also all paths should return a value. Bung return 0; at the end

Upvotes: 3

Related Questions