参数的解析:getopt_long
getopt_long可以解析短参数(-a -b -c)和长参数(--add --delete --create),其定义在getopt.h中。
函数:
int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *indexptr)
参数:
argv:需要解析的参数字符串
argc:argv中字符串的数量
shortopts: 支持的短参数的字符串
longopts: 支持长参数的struct option集合
indexptr: *indexptr表明参数在longopts中的索引位置。
struct option
{
const char *name; //长参数名
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg; //no_argument(0),required_argument(1),optional_argument(2)
int *flag; // 如果flag非NULL,则会将val保存至*flag中,当做标志。
int val; // 短参数名
};
全局变量:
(1)optarg:表示当前选项对应的参数值。
(2)optind:表示的是下一个将被处理到的参数在argv中的下标值。
(3)optopt:表示没有被未标识的选项。
完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
/* Flag set by ‘--verbose’. */
static int verbose_flag;
opterr = 1;
int main(int argc, char **argv)
{
int c;
static struct option long_options[] =
{
/* These options set a flag. */
{"verbose1", no_argument, &verbose_flag, 1},
{"verbose2", no_argument, &verbose_flag, 2},
{"verbose3", no_argument, &verbose_flag, 3},
{"brief", no_argument, &verbose_flag, 0},
/* These options don’t set a flag.
We distinguish them by their indices. */
{"add", no_argument, 0, 'a'},
{"append", no_argument, 0, 'b'},
{"delete", required_argument, 0, 'd'},
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 'f'},
{0, 0, 0, 0}};
/* getopt_long stores the option index here. */
int option_index = 0;
char shortOpt[512] = {0};
int cnt = 0;
for (int i = 0; i < sizeof(long_options) / sizeof(struct option); i++)
{
if (long_options[i].val >= 'a' && long_options[i].val <= 'z')
{
shortOpt[cnt++] = long_options[i].val;
if (long_options[i].has_arg == required_argument)
{
shortOpt[cnt++] = ':';
}
else if (long_options[i].has_arg == optional_argument)
{
shortOpt[cnt++] = ':';
shortOpt[cnt++] = ':';
}
}
}
printf("line: [%d] shortOpt[%s]\n", __LINE__, shortOpt);
while (1)
{
c = getopt_long(argc, argv, shortOpt,
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
printf("optind[%d],argc[%d]\n", optind, argc);
printf("optarg=%s\n", optarg);
if (optind < argc)
{
printf("next optarg=%s\n", argv[optind]);
}
switch (c)
{
case 0:
/* If this option set a flag, do nothing else now. */
if (long_options[option_index].flag != 0)
break;
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case 'a':
puts("option -a\n");
break;
case 'b':
puts("option -b\n");
break;
case 'c':
printf("option -c with value `%s'\n", optarg);
break;
case 'd':
printf("option -d with value `%s'\n", optarg);
break;
case 'f':
printf("option -f with value `%s'\n", optarg);
break;
case '?':
/* getopt_long already printed an error message. */
break;
default:
abort();
}
}
/* Instead of reporting ‘--verbose’
and ‘--brief’ as they are encountered,
we report the final status resulting from them. */
if (verbose_flag)
printf("verbose flag is set:%d\n", verbose_flag);
/* Print any remaining command line arguments (not options). */
if (optind < argc)
{
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
putchar('\n');
}
exit(0);
}

浙公网安备 33010602011771号