I have the following code
#include <stdio.h>
#include <getopt.h>
int main(int argc, char* argv[]){
const struct option longopts[]={
{"one", required_argument, 0, '1'},
{"two", required_argument, 0, '2'},
{"three", required_argument, 0, '3'},
{"four", required_argument, 0, '4'},
{"five", required_argument, 0, '5'},
{0,0,0,0}
};
const char* shortopts="1:2:3:4:5:";
int c;
c = -1;
for(;;){
int optind = 0;
c = getopt_long(argc, argv, shortopts, longopts, &optind);
if(c<0)
break;
switch(c){
case 0:
case '1':
case '2':
case '3':
case '4':
case '5':
fprintf(stdout, "----------------------------------------\n");
fprintf(stdout, "c = %c\n", c);
fprintf(stdout, "optindd = %d\n", optind);
fprintf(stdout, "val = %c, \n", longopts[optind].val);
fprintf(stdout, "name = %s\n", longopts[optind].name);
fprintf(stdout, "optarg = %s\n", optarg);
break;
}
}
}
Input:
./a.out --one 1 -2 two --three 3 -4 four --five 5
Expected output:
I want to print members of the struct option (name and val) when its corresponding shortopt/longopt is encountered.
The above code prints the following with some unexpected outputs :
----------------------------------------
c = 1
optindd = 0
val = 1,
name = one
optarg = 1
----------------------------------------
c = 2
optindd = 0 // expected 1
val = 1, // expected 2
name = one // expected two
optarg = two
----------------------------------------
c = 3
optindd = 2
val = 3,
name = three
optarg = 3
----------------------------------------
c = 4
optindd = 0 // expected 3
val = 1, // expected 4
name = one // expected four
val = four
----------------------------------------
c = 5
optindd = 4
val = 5,
name = five
val = 5
I am using Ubuntu 14.04.
The longindex
return argument to getopt_long
is only set for long options, not for short options. There is no way for getopt_long
to know which long option corresponds to a given short option (although the correspondence may seem obvious to you). If a short option is found, the longindex
variable is unchanged, so you should initialize to a value you can recognized (like -1) rather than initializing it to 0.
By the way, optind
is a global variable maintained by getopt
, which you will need in order to process positional arguments once you have finished with the flags. It's unwise (though legal) to cover this variable with a local variable with the same name; it is both confusing for readers and awkward when you need the value.
None of that helps you identify the long option corresponding to a given short option. That is totally your responsibility, if you feel you need that information. You could, for example, search the longopts structure for a val
corresponding to the short option found; you would then have to deal with the possibilities that a given short option occurs zero or more than one times in that structure.
As a simple example, instead of:
int optindex = 0;
c = getopt_long(argc, argv, shortopts, longopts, &optindex);
you could do something like:
int optindex = -1;
c = getopt_long(argc, argv, shortopts, longopts, &optindex);
if (optindex == -1) {
for (optindex = 0; longopts[optindex].name, ++optindex) {
if (longopts[optindex].val == c) break;
}
if (longopts[optindex].name == NULL) {
// the short option was not found; do something
}
}