getopt_long() and parameters that aren't flags?
I'm trying to use the getopt_long()
function for the first time only I'm having problems with arguments that aren't flags. For instance, in my code when a unknown argument is given I want to use it as a input file. When I run this with only a file name it is not printed, if I first use a flag, any flag, then I can print it.
How can I fix this?
#include <stdio.h>
#include <getopt.h>
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{"algorithm", required_argument, 0, 'a'},
{0, 0, 0, 0}
};
int main(int argc, char *argv[]) {
int c;
int option_index = 0;
while(42) {
c = getopt_long(argc, argv, "hi:o:a:", long_options,
&option_index);
if(c == -1)
break;
switch(c) {
case 'h': /* --help */
printf("--help 开发者_开发知识库flag\n");
break;
case 'i': /* --input */
printf("--input flag\n");
break;
case 'o': /* --output */
printf("--output flag\n");
break;
case 'a': /* --algorithm */
printf("--algorithm flag \n");
break;
default: /* ??? */
fprintf(stderr, "Invalid option");
return 1;
}
if(optind < argc) {
printf("other arguments: ");
while(optind < argc) {
printf ("%s ", argv[optind]);
optind++;
}
printf("\n");
}
}
return 0;
}
The loop should only contain the switch. Process the residual arguments in a separate (not nested) loop:
#include <stdio.h>
#include <getopt.h>
static struct option long_options[] =
{
{"help", no_argument, 0, 'h'},
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{"algorithm", required_argument, 0, 'a'},
{0, 0, 0, 0}
};
int main(int argc, char *argv[])
{
int opt;
int option_index = 0;
int i;
while ((opt = getopt_long(argc, argv, "hi:o:a:", long_options, &option_index)) != -1)
{
switch(opt)
{
case 'h': /* --help */
printf("--help flag\n");
break;
case 'i': /* --input */
printf("--input flag (%s)\n", optarg);
break;
case 'o': /* --output */
printf("--output flag (%s)\n", optarg);
break;
case 'a': /* --algorithm */
printf("--algorithm flag (%s)\n", optarg);
break;
default: /* ??? */
fprintf(stderr, "Invalid option %c\n", opt);
return 1;
}
}
for (i = optind; i < argc; i++)
printf("Process: %s\n", argv[i]);
return 0;
}
There is a way to have GNU getopt()
and getopt_long()
return file name arguments as if they were options with the 'letter' ^A '\1'; use '-
' as the first character of the short options string, and trap '\1
' in the switch; the value of optarg
is the name of the file.
#include <stdio.h>
#include <getopt.h>
static struct option long_options[] =
{
{"help", no_argument, 0, 'h'},
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{"algorithm", required_argument, 0, 'a'},
{0, 0, 0, 0}
};
int main(int argc, char *argv[])
{
int opt;
int option_index = 0;
int i;
while ((opt = getopt_long(argc, argv, "-hi:o:a:", long_options, &option_index)) != -1)
{
switch(opt)
{
case 'h': /* --help */
printf("--help flag\n");
break;
case 'i': /* --input */
printf("--input flag (%s)\n", optarg);
break;
case 'o': /* --output */
printf("--output flag (%s)\n", optarg);
break;
case 'a': /* --algorithm */
printf("--algorithm flag (%s)\n", optarg);
break;
case '\1':
printf("File: %s\n", optarg);
break;
default: /* ??? */
fprintf(stderr, "Invalid option %c\n", opt);
return 1;
}
}
for (i = optind; i < argc; i++)
printf("Process: %s\n", argv[i]);
return 0;
}
However, you do need the loop after the argument processing loop in case your cantankerous user types:
program -- abc def
The '--
' terminates the while()
loop without processing the file name arguments.
It doesn't work because you break out of the outer while
loop when getopt_long
returns -1 (which indicates that there are no more options).
You need to move the if (optind < argc)
block out of the outer while
loop; it doesn't belong there anyway. This might be clearer if you wrote that outer while
loop as:
while ((c = getopt_long(...)) != -1)
{
switch (c)
{
/* Deal with flags. */
}
}
精彩评论