Parsing command line options with multiple arguments [getopt?]
Your code was actually very, very close to working. The only thing you were missing is that getopt
only expects you to consume one argument after -l
, and therefore continues command line parsing following the first argument to -l
. Since you're going behind its back and pulling off more arguments, you have to tell getopt
where to start parsing the command line again.
getopt
stores that information in the global variable optind
. When I added the line:
optind = index - 1;
before the break;
in your l
case, your code started working.
Salamander
Updated on June 05, 2022Comments
-
Salamander about 2 years
I need my program to get several arguments from command line, the syntax is as follows:
getpwd -l user1 user2 ... -L -X -S...
So, I need to get the users behind the
-l
option. I tried usinggetopt
, but without much luck, it only works when I place the other options before the-l
:getpwd -L -X -S ... -l user1 user2 ...
My code (for
-l
and-S
):while((c = getopt(argc, argv, "l:S")) != -1){ switch(c){ case 'l': index = optind-1; while(index < argc){ next = strdup(argv[index]); /* get login */ index++; if(next[0] != '-'){ /* check if optarg is next switch */ login[lcount++] = next; } else break; } break; case 'S': sflag++; /* other option */ break; case ':': /* error - missing operand */ fprintf(stderr, "Option -%c requires an operand\n", optopt); break; case '?': /* error - unknown option */ fprintf(stderr,"Unrecognized option: -%c\n", optopt); break; } }
optopt
andoptind
areextern int
.So, the question is: Can I use the
getopt()
function (orgetopt_long()
) ? Or do I have to write my own parser to get what I need ? -
Salamander over 11 yearsFor some reason
optind = index-1
works for me ... I will do look at it more closely tomorrow. But thanks so much. I am amazed this works ... I found everywhere that getopts() can't be used this way :D -
rra over 11 yearsApologies, you are entirely correct, it should be
optind - 1
. A flaw in my testing; I forgot to test that the following option was properly parsed. I'll fix that.