getopt_long()备忘
用途
getopt_long()用于解析类似于 --version --config configfile 这样的长选项。
如何使用
1、定义struct option数组
struct option { cosnt char* name; //长选项的名称。 比如 ./xx --config demo.conf 中,--config 这一项对应的name 为 config int has_arg;//说明选项是否带有参数。为true时, 以./xx --config demo.conf 启动xx时, 指明--config这一项带有参数 int *flag;//标志位,用来指定get_opt_long()的返回方式。 分两种:1:匹配到名称为name的参数时,直接返回val值; 2:匹配到名称为name的参数时,将val保存到flag中,返回值为0 int val; //预定义的返回值 }
定义如下所示的struct option数组,指明要接收的长选项名称,是否需要参数以及匹配到时返回的方式。
static struct option long_options[] = { { "add", no_argument, 0, 'S' }, { "Add", required_argument, 0, 'A' }, { "delete", no_argument, 0, 'd' }, { "Delete", required_argument, 0, 'D' }, { "verbose", no_argument, 0, 'v' }, { "Verbose", required_argument, 0, 'V' }, { "Create", no_argument, 0, 'c'}, { "create", required_argument, 0, 'C'}, { 0,0,0,0 } };
如上定义了struct option数组, 其中flag位均设为0,代表当 getopt_long()匹配到长选项后,直接以第四位定义的val作为返回值 。
指明了我们想要接收如下形式的选项(选项先后顺序不重要)
--add --Add var --delete --Delete var --verbose --Verbose var --Create --create var
2、while循环中解析
getopt_long()的函数原型如下:
1 int getopt_long(int argc, // 2 char * const argv[],// 3 const char *optstring,//短选项的解析规则 4 const struct option *longopts,//指向struct option[] 长选项的解析规则 5 int *longindex);//匹配到的长选项在longopts中的地址
具体如何使用getopt_long()呢?如下所示,while循环中的getopt_long()会不断解析选项字符串,当匹配到了确定的长选项时,会更新option_index、optarg(如果选项有参数的话),返回指定的val,因此我们可以按照switch(val)的方式来完成后续工作。
测试代码
1 /***** 2 *File Name: opt.c 3 *Author: ckw 4 *Created: 2020-07-12 23:07:28 5 *Last Modified: 2020-07-12 23:07:28 6 ***/ 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <getopt.h> 10 11 int main(int argc,char **argv){ 12 static struct option long_options[] = { 13 14 { "add", no_argument, 0, 'S' }, 15 { "Add", required_argument, 0, 'A' }, 16 { "delete", no_argument, 0, 'd' }, 17 { "Delete", required_argument, 0, 'D' }, 18 { "verbose", no_argument, 0, 'v' }, 19 { "Verbose", required_argument, 0, 'V' }, 20 { "Create", no_argument, 0, 'c'}, 21 { "create", required_argument, 0, 'C'}, 22 { 0,0,0,0 } 23 }; 24 char * format="ab:";//解析短选项 如 -a -b。 这里的意思是 -a 后面无参数, -b 后面要有参数 25 int opt; //返回值,当struct option中的flag=0时,getopt_long()返回struct option中的val 26 int option_index=0; 27 28 while((opt=getopt_long(argc,argv,format,long_options,&option_index))!=-1){
//根据返回值区分匹配到的情况 29 switch(opt){
30 case 'S': // 当匹配到 --add 时 31 printf("option --append\n"); 32 printf("name:%s\n",long_options[option_index].name);//此时,option_index为struct option long_options[]中匹配项的索引值。 33 break; 34 case 'd': // 当匹配到 --delete 时 35 printf("option delete\n"); 36 break; 37 case 'v': 38 printf("option verbose\n"); 39 break; 40 case 'c': 41 printf("option c\n"); 42 break; 43 case 'A': 44 printf("option %s\n",optarg); //当匹配到了 --add arg 时,optarg被设置为arg 45 break; 46 case 'D': 47 printf("option %s\n",optarg); 48 break; 49 case 'V': //当匹配到 --Verbose arg 时 50 printf("option %s\n",optarg); 51 break; 52 case 'C': //当匹配到 --create arg 时 53 printf("option %s\n",optarg); 54 break; 55 } 56 } 57 }
测试结果
1 user@user:~/tmp$ ./a.out --add --Add hello --delete -a 2 option --append 3 name:add 4 option hello 5 option delete
如上所示,对有参数和无参数的长选项,均能成功处理
参考链接:http://blog.zhangjikai.com/2016/03/05/%E3%80%90C%E3%80%91%E8%A7%A3%E6%9E%90%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0--getopt%E5%92%8Cgetopt_long/