Search code examples
cdebuggingcommand-line-argumentsgetoptgetopt-long

Using getopt in C for command line arguments


I am working on trying to take in command line arguments. If I want to have multiple optional command line arguments how would I go about doing that? For example you can run the program in the following ways: (a is required every instance but -b -c -d can be given optionally and in any order)

./myprogram -a
./myprogram -a -c -d
./myprogram -a -d -b

I know that getopt()'s third argument is options. I can set these options to be "abc" but will the way I have my switch case set up causes the loop to break at each option.


Solution

  • The order doesn't matter so far as getopt() is concerned. All that matters is your third argument to getopt() (ie: it's format string) is correct:

    The follow format strings are all equivalent:

    "c:ba"
    "c:ab"
    "ac:b"
    "abc:"
    

    In your particular case, the format string just needs to be something like "abcd", and the switch() statement is properly populated.

    The following minimal example¹ will help.

    #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;
    }
    

    ¹Example taken from the GNU manual