Salamander Salamander - 16 days ago 6
C Question

Parsing command line options with multiple arguments [getopt?]

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 using
getopt
, 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
and
optind
are
extern int
.

So, the question is: Can I use the
getopt()
function (or
getopt_long()
) ? Or do I have to write my own parser to get what I need ?

rra rra
Answer

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.