Can someone help me with the getopt function?
When I do the following in main:
char *argv1[] = {"testexec","-?"};
char *argv2[] = {"testexec","-m","arg1"};
int cOption;
/* test for -? */
setvbuf(stdout,(char*)NULL,_IONBF,0);
printf("\n argv1 ");
while (( cOption = getopt (2, argv1, "m:t:n:fs?")) != -1) {
switch(cOption){
case 'm':
printf("\n -m Arg : %s \n",optarg);
break;
case '?':
printf("\n -? Arg ");
break;
case 'n':
printf("\n -n Arg : %s \n",optarg);
break;
}
}
printf("\n argv2 ");
while (( cOption = getopt (3, argv2, "m:t:n:fs?")) != -1) {
switch(cOption){
case 'm':
printf("\n -m Arg : %s \n",optarg);
break;
case '?':
printf("\n -? Arg : %s \n",optarg);
break;
case 'n':
printf("\n -n Arg : %s \n",optarg);
break;
}
}
I'm running this code on rhel3 which uses old libc version. I don't know which one to be exact.
Now the problem is getopt doesn't work the second time with argv2. But if I comment out the first getopt call with argv1 , it works.
Can someone tell me what am I doing wrong here?
Is there any reason why you are not using getopt_long() instead? On most platforms, getopt() just calls _getopt_long() with a switch to disable long arguments. That's the case with almost every platform that I know of (still in use), including Linux, BSD and even emerging OS's like HelenOS -, I know, I was the one who ported getopt to its libc :)
It is much easier on ANYONE using your program to have long options at least until they get used to using it.
getopt_long() will allow you to use two (or more) option indexes that can stay 'live' after they are done processing arguments, only the internal (global, non-reentrant) one would have to be re-set which is no big deal.
This lets you easily compare the argument count to the number of options actually passed in both invocations with many other benefits .. please consider not using the antiquated interface.
Look at getopt.h, you'll see what I mean.
As stated in the man page:
"A program that scans multiple argument vectors, or rescans the same vector more than once, and wants to make use of GNU extensions such as '+' and '-' at the start of optstring, or changes the value of POSIXLY_CORRECT between scans, must reinitialize getopt() by resetting optind to 0, rather than the traditional value of 1. (Resetting to 0 forces the invocation of an internal initialization routine that rechecks POSIXLY_CORRECT and checks for GNU extensions in optstring.)"
argv1 and 2 must end in 0:
Edit: OK, I read the getopt man page and I found this:
So, making optind=1 between the two calls at getopt makes it work as expected.
The
getopt()
function uses some global variables, likeoptind
andoptarg
, to store state information between calls. After you finish processing one set of options, there is data left in those variables that is causing problems with the next set of options. You could potentially try to resetgetopt
's state between calls by clearing the variables, but I'm not sure that would work since the function might use other variables which aren't documented and you'd never know if you'd gotten them all; besides, it would be absolutely nonportable (i.e. if the implementation ofgetopt()
changes, your code breaks). See the man page for details. Best not to usegetopt()
for more than one set of arguments in a given program if you can help it.I'm not sure if there is an actual function to reset
getopt
's state (or perhaps a reentrant version of the function, which lets you store the state in your own variables)... I seem to remember seeing something like that once, but I can't find it now that I look :-/