Reputation: 423
So I searched high and low for an answer to this question and all I could find was someone who poorly asked the same question 2 years ago and was never really answered (option followed by a option in getopt [where the earlier option was expecting a value]).
Currently, I am writing a program that is supposed to accept command line options and arguments.
The command is supposed to create and manipulate an archive file supplied through the command line. I am using getopt()
. The usage for the command is oscar [options] [archive-file] [member files]
however some of the options do not require arguments. Such as a '-v' flag which stands for verbose and simply causes other actions in the file to spit out more print statements than the default.
Here is my code for using getopt():
//declaring some variables to be used by getopt
18 extern char *optarg; //pointer to options that require an argument
19 extern int optind; //index into main()'s argument list (argv[])
20
21 int getOptReturn = 0; //int that stores getopt's return (used to check if it is done parsing)
22 int error = 0; //flag for '?' case if getopt doesn't receive proper input
23
24 //flags for all the options
25 int a_flag, A_flag, v_flag, C_flag, d_flag, e_flag, h_flag,
26 m_flag, o_flag, t_flag, T_flag, E_flag, V_flag, u_flag = 0;
27
28 int i; //for loops index
29
30 char *aname;
31
32 //while parsing options
33 while((getOptReturn = getopt(argc, argv, "a:A:Cd:e:E:hm:otTu:vV")) != -1)
34 {
35 //debugging
36 printf("optind: %d, option: %c, optarg: %s \n", optind, argv[optind], optarg);
37 printf("%d\n", argc);
38
39 //switch options and set appropriate flags
40 switch(getOptReturn)
41 {
42 case 'a':
43 printf("-a option received\n");
44 //turn add flag on
45 a_flag = 1;
46 aname = optarg;
47 printf("argument supplied to -a: %s \n", aname);
48 break;
49 case 'A':
50 printf("-A option received\n");
51 //turn add all flag on
52 A_flag = 1;
53 aname = optarg;
54 printf("argument supplied to -A: %s \n", aname);
55 break;
56 case 'v':
57 printf("-v option received\n");
58 //turn verbose flag on
59 v_flag = 1;
60 printf("verbose flag turned on!\n");
61 break;
Now the problem that I'm facing is that the order I'm passing the option characters in currently matters when it is not supposed to.
For example:
If i call the function with ./oscar -va archive
the code functions properly and v
causes the v flag to be turned on, and a
is processed with archive
as the argument because I required a
to have an argument inside of getopt()
.
However, if I call the function with ./oscar -av archive
the code reads in a
and assigns v
as its required argument instead of reading v
as an option and using archive
as the argument for a
.
Is there any way I can tell getopt()
to skip over other option values in argv[] so that I can call the function from the command line with all sorts of combinations and not worry about order such as:
./oscar -avo archive file1 file2 file3...
./oscar -a A v archive file1 file2...
Upvotes: 1
Views: 1334
Reputation: 423
According to user n.m.
's comment, this is just how command line arguments are supposed to behave as specified by the POSIX guidelines.
From his comment:
"One or more options without option-arguments, followed by at most one option that takes an option-argument, should be accepted when grouped behind one '-' delimiter."
If you desire the functionality I was looking for, you need to use the external variable that getopt supplies you with: optind
paired with argc
and argv[]
to manually handle more options that require arguments.
Thanks for reading.
Upvotes: 2