问题
I need to call my program like this:
./program hello -r foo bar
I take hello out of argv[1], but i am having trouble with value bar, also should i change "r:" to something else?
while((c = getopt(argc, argv, "r:")) != -1){
switch(i){
...
case 'r':
var_foo = optarg;
//shell like argument shift here?
var_bar = optarg;
break;
...}
I know I could do this with passing through argv, but is there a way to do it with getopt similar way as in bash?
Thanks.
回答1:
bar
is not an option argument in the eyes of getopt
. Rather, GNU getopt
rearranges the positional arguments so that at the end of the processing, you have argv[3]
being "hello" and argv[4]
being "bar". Basically, when you're done getopting, you still have positional arguments [optind, argc)
to process:
int main(int argc, char * argv[])
{
{
int c;
while ((c = getopt(argc, argv, ...)) != -1) { /* ... */ }
}
for (int i = optind; i != argc; ++i)
{
// have positional argument argv[i]
}
}
回答2:
It depends on whether you're using GNU getopt() or not, and if you are, whether POSIXLY_CORRECT
is set in the environment.
Classically (meaning non-GNU getopt()), all the option arguments must precede any non-option (file name) arguments. That would mean you have four non-option arguments.
If you have GNU getopt()
and do not have POSIXLY_CORRECT
set, then it will process option arguments anywhere on the command line. In that case, you'd have one option, -r
with the argument value foo
, and two non-option arguments (hello
and bar
).
To get Classic getopt()
to recognize the -r
, you'd have to require the first (non-option) argument and only then call getopt()
at all:
int main(int argc, char **argv)
{
char *cmd = argv[1];
int opt;
argv[1] = argv[0];
argv++;
argc--;
while ((opt = getopt(argv, argc, "r:")) != EOF)
{
switch (opt)
{
case 'r':
...capture optarg...
break;
default:
...report error....
break;
}
}
for (int i = optind; i < argc; i++)
process_non_option_argument(cmd, argv[i]);
return(0);
}
GNU getopt
can also return non-option arguments if you enable it to do so. Other than that, the bar
argument will always be treated as a non-option argument.
来源:https://stackoverflow.com/questions/10058669/getopt-shift-optarg