用Linux下的getopt类函数解析参数列表


在GNU下有getopt类的函数可以轻松解析参数列表,省去很多烦恼,定义如下:

#include <unistd.h>
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#define _GNU_SOURCE
#include <getopt.h>
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);

需要对长参数(非一个字符)进行解析的时候要用到getopt_long(),这个函数有个参数struct option的定义为:

struct option {
const char *name;
int has_arg;
int *flag;
int val;
};

这个结构体定义属于头文件<getopt.h>

对与这个结构体的详细解释为:

struct option {
const char *name; // 名字
int has_arg;        // 0 没有参数, 1 必须有参数, 2 可选参数
int *flag;        // 如果这个指针为NULL,那么getopt_long()返回该结构val字段中的数值。如果该指针不为NULL,getopt_long()会使得它所指向的变量中填入val字段中的数值,并且getopt_long()返回0。如果flag不是NULL,但未发现长选项,那么它所指向的变量的数值不变。
int val;            // 发现了长选项时的返回值,或者flag不是 NULL时载入*flag中的值。典型情况下,若flag不是NULL,那么val是个真/假值,譬如1 或0;另一方面,如果flag是NULL,那么val通常是字符常量,若长选项与短选项一致,那么该字符常量应该与optstring中出现的这个选项的参数相同。
};// 此数据类型的数据最后一个元素必须是0

下面是一个例子:

#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>
// 定义长参数
static struct option long_options[] = {
{"addsg", 0, 0, '1'},
{"rmsg", 0, 0, '2'},
{"addnode", 0, 0, '3'},
{"rmnode", 0, 0, '4'},
{"from", 1, 0, 'f'},
{"to", 1, 0, 't'},
{"help", 0, 0, 'h'},
{"version", 0, 0, 'v'},
{"reflush", 0, 0, 'r'},
{0, 0, 0, 0}
};
// 定义短参数
char* const short_options = "1234f:t:hvr";
// 循环解析参数,并进行处理
int get_options (int argc, char **argv)
{
int c;
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
c = getopt_long (argc, argv, short_options, long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '1':
printf ("start addnode function\n");
break;
case '2':
printf ("start removesg function\n");
break;
case '3':
printf ("start addnode function\n");
break;
case '4':
printf ("start removenode function\n");
break;
case 'h':
printf ("show help\n");
break;
case 'v':
printf("show version\n");
break;
case 'f':
printf ("src ip is : '%s'\n", optarg);
break;
case 't':
printf ("dst ip is : '%s'\n", optarg);
break;
case 'r':
printf ("should reflush data\n");
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
return 0;
}
int main (int argc, char **argv)
{
printf("main function\n");
get_options(argc, argv);     // 将程序的参数直接传给函数,用以解析
return 0;
}

相关内容