I am trying to get getopt to work with my C program, but I have found that it is not working. Here is the function that doesn't work
char* getFlagArg(int argc, char **argv, char flag) {
extern char *optarg;
extern int optind, optopt, opterr;
char opt;
char options[3] = {flag,':',0};
while((opt = getopt(argc, argv, options)) != -1) {
if(opt == flag)
return optarg;
}
return "";
}
When I run this code, it immediately exits the loop (the loop does not run even once). I can't figure out why this is happening. I have verified that argc, argv, and options are all what I expect them to be. Thoughts? Please and thank you!
The point I was trying to get at in the question's comments was this:
char *arg;
arg = getFlagArg (argc, argv, 'b');
printf ("-b arg = %s\n", arg);
arg = getFlagArg (argc, argv, 'u');
printf ("-u arg = %s\n", arg);
If you have called getFlagArg
or getopt
already, the second call will possibly fail. Imagine you had an option -b
that accepted an argument, and the command line was ./a.out -u foo -b quux filename
. Because you searched for -b
first, optind
will be 5, and searching for -u
will fail because optind
is greater than 1, which is the value optind
must be to find the -u
option in the example command line I provided.
You will need to "reset" getopt
by setting optind
to 1. Of course, we would need to see the code calling getFlagArg
if this isn't the problem.
Edit
Options without arguments are allowed to be in the same argv
element. getopt
can handle this, but if you have two options -a
and -c
, ./a.out -cau foo
will work with getopt
, but you cannot necessarily find -c
after finding -a
even by setting optind
to 1 again. Only after you go through -u foo
(or any other option requiring an argument) will you be able to reset optind
and restart parsing.
FreeBSD and likely some other BSD clones provide a nonstandard optreset
variable to handle this sort of case. Glibc on Linux, however, does not, so beware of this strange "quirk" of getopt
.