Reputation: 2386
Depending on the format with which I pass options to this program, the variable optind
will either increment properly to reflect the next option value or it will not.
If I use ./cfind -aru
, I get the following (strange) output.
optind: 1
aflag detected
optind: 1
optind: 1
rflag detected
optind: 1
optind: 2
uflag detected
optind: 2
Notice that optind does not increment from aflag to rflag but it does increment from rflag to uflag.
However, when I use the format ./cfind -a -r -u, I get the following (expected) output.
optind: 2
aflag detected
optind: 2
optind: 3
rflag detected
optind: 3
optind: 4
uflag detected
optind: 4
This is the output I desire.
My code for this function is as follows.
#include "cfind.h"
#define OPTLIST "acdirstu" // list of valid options
void ProcOpt(int argc, char *argv[]) {
int opt = 0; // default value
opterr = 0; // prevent getopt from passing error message to stderr buffer
// char *filenm = NULL; // pointer to the path name
while((opt = getopt(argc, argv, OPTLIST)) != -1) {
switch (opt) {
case 'a':
fprintf(stdout, "optind: %i\n", optind);
aflag = true;
assert(aflag == true);
fprintf(stdout, "aflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 'c':
fprintf(stdout, "optind: %i\n", optind);
cflag = true;
assert(cflag == true);
fprintf(stdout, "cflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 'd':
fprintf(stdout, "optind: %i\n", optind);
dflag = true;
assert(cflag == true);
fprintf(stdout, "dflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 'i':
fprintf(stdout, "optind: %i\n", optind);
iflag = true;
assert(iflag == true);
fprintf(stdout, "iflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 'r':
fprintf(stdout, "optind: %i\n", optind);
rflag = true;
assert(rflag == true);
fprintf(stdout, "rflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 's':
fprintf(stdout, "optind: %i\n", optind);
sflag = true;
assert(sflag == true);
fprintf(stdout, "sflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 't':
fprintf(stdout, "optind: %i\n", optind);
tflag = true;
assert(tflag == true);
fprintf(stdout, "tflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
case 'u':
fprintf(stdout, "optind: %i\n", optind);
uflag = true;
assert(uflag == true);
fprintf(stdout, "uflag detected\n");
fprintf(stdout, "optind: %i\n", optind);
break;
default:
usage();
}
}
}
Am I doing something wrong? Is there something I am misunderstanding about getopt()
and how it increments optind
?
Thank you.
Upvotes: 0
Views: 1325
Reputation: 414
#include <stdio.h> #include <unistd.h>
extern char *optarg;
extern int optind;
int main (int argc, char** argv) {
int c;
printf("--------- options: ---------\n");
while ((c = getopt (argc,argv,"abcd:")) != -1) {
printf("opt: %c arg %s\n", (char)c, optarg);
}
argc -= optind - 1;
argv += optind - 1;
printf("------ remaining args: ------\n");
for (int i = 1; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
}
Upvotes: 0
Reputation: 4922
Put this at the start of your program to see what is going on:
for (int i = 0; i < argc; ++i)
printf("Param %d: %s\n", i, argv[i]);
Upvotes: 0
Reputation: 6739
That output looks right to me.
optind
is the index of the next argument to be processed. When you have all the options together, they're all in argv[1]
, so optind
remains at 1 until you've processed the u
option. At that point, since everything in argv[1]
has been consumed, optind
is set to 2.
When the options are all in separate elements of argv
, optind
is always the index of the next argument to be processed.
See http://man7.org/linux/man-pages/man3/getopt.3.html.
Upvotes: 1