Search code examples
cloopsargvargc

Iterating over argv[] produces segmentation fault


I'm writing a program that reads "flags" from the command line as well as the program name. I want the program to read several flags (-i, -c and -n) and execute different functions when one or a combination of flags is called.

This is the code I started to write:

  printf("Argv 0: %s\n", argv[0]);
  printf("Argv 1: %s\n", argv[1]);
  printf("Argv 2: %s\n", argv[2]);

  for (int i = 1; i <= argc + 1; i++) {
    if (strcmp("-i", argv[i]) == 0) {
      printf("%s\n", "found -i"); 
    }
    else{
      printf("%s\n", "did not find -i");
    }

  }

Just experimenting with one flag (-i), but I want it the read one or several flags at the same time and it to call the corresponding functions.

When I execute the program:

./program-name test -i
Argv 0: test
Argv 1: -i
Argv 2: (null)
found -i
Segmentation fault 

Solution

  • Don't redo old code that is proven solid. It wastes time and duplicates effort. As a long time C coder, I always (when I remember) go and look at code bases for something first before I try to start from scratch. I repurpose first then create. I'm smart enough to know there were lots of smarterer coders that went before me.

    Use the free and working getopt() and getopt_long() functions to parse command line arguments for you. There are lots of examples in code bases if you google search "getopt example" but here is the GNU C tutorial.

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int
    main (int argc, char **argv)
    {
      int aflag = 0;
      int bflag = 0;
      char *cvalue = NULL;
      int index;
      int c;
    
      opterr = 0;
    
      while ((c = getopt (argc, argv, "abc:")) != -1)
        switch (c)
          {
          case 'a':
            aflag = 1;
            break;
          case 'b':
            bflag = 1;
            break;
          case 'c':
            cvalue = optarg;
            break;
          case '?':
            if (optopt == 'c')
              fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
              fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
              fprintf (stderr,
                       "Unknown option character `\\x%x'.\n",
                       optopt);
            return 1;
          default:
            abort ();
          }
    
      printf ("aflag = %d, bflag = %d, cvalue = %s\n",
              aflag, bflag, cvalue);
    
      for (index = optind; index < argc; index++)
        printf ("Non-option argument %s\n", argv[index]);
      return 0;
    }