在实际程序之中我们经常要对命令行参数进行分析. 比如我们有一个程序a可以接受许多参数.一个可能的情况是 a -d print --option1 hello --option2 world 那么我们如何对这个命令的参数进行分析了?.经常用函数是getopt和getopt_long. #include <unistd.h> #include <getopt.h>
int getopt(int argc,char const **argv, const char *optstring); int getopt_long(int argc,char const **argc, const char *optstring,const struct option *longopts, int *longindex);
extern char *optarg; extern int optind,opterr,optopt;
struct option { char *name; int has_flag; int *flag; int value; };
getopt_long是getopt的扩展.getopt接受的命令行参数只可以是以(-)开头,而getopt_long还可以接受(--)开头的参数.一般以(-)开头的参数的标志只有一个字母,而以(--)开头的参数可以是一个字符串.如上面的 -d,--option1选项. argc,和argv参数是main函数的参数.optstring指出了我们可以接受的参数.其一般的形式为:参数1[:]参数2[:].... 其中参数是我们可以接受的参数,如果后面的冒号没有省略,那么表示这个参数出现时后面必需要带参数值. 比如一个optstring为abc:d:表示这个参数选项可以为a,b,c,d其中c,d出现时候必须要有参数值.如果我们输入了一个我们没有提供的参数选项.系统将会说 不认识的 选项. getopt返回我们指定的参数选项.同时将参数值保存在optarg中,如果已经分析完成所有的参数函数返回-1.这个时候optind指出非可选参数的开始位置.
#include <stdio.h> #include <unistd.h>
int main(int argc,char **argv) { int is_a,is_b,is_c,is_d,i; char *a_value,*b_value,*c_value,temp;
is_a=is_b=is_c=is_d=0; a_value=b_value=c_value=NULL;
if(argc==1) { fprintf(stderr,"Usage:%s [-a value] [-b value] [-c value] [-d] arglist .../n", argv[0]); exit(1); }
while((temp=getopt(argc,argv,"a:b:c:d"))!=-1) { switch (temp) { case 'a': is_a=1; a_value=optarg; break; case 'b': is_b=1; b_value=optarg; break; case 'c': is_c=1; c_value=optarg; break; case 'd': is_d=1; break; } }
printf("Option has a:%s with value:%s/n",is_a?"YES":"NO",a_value); printf("Option has b:%s with value:%s/n",is_b?"YES":"NO",b_value); printf("Option has c:%s with value:%s/n",is_c?"YES":"NO",c_value); printf("OPtion has d:%s/n",is_d?"YES":"NO"); i=optind; while(argv[i]) printf(" with arg:%s/n",argv[i++]); exit(0); }
getopt_long比getopt复杂一点,不过用途要比getopt广泛.struct option 指出我们可以接受的附加参数选项. name:指出长选项的名称(如我们的option1) has_flag:为0时表示没有参数值,当为1的时候表明这个参数选项要接受一个参数值.为2时表示参数值可以有也可以没有. 指出函数的返回值.如果为NULL,那么返回val,否则返回0.并将longindex赋值为选项所在数组(longopts)的位置.
/* 这个实例是从 GNU Libc 手册上看到的 */
#include <stdio.h> #include <stdlib.h> #include <getopt.h>
int main (int argc, char **argv) { int c;
while (1) { struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, /* 返回字符c,等同于 -c 选项 */ {"create", 0, 0, 'c'}, {"file", 1, 0, 0}, /* 数组结束 */ {0, 0, 0, 0} }; /* getopt_long stores the option index here. */ int option_index = 0;
c = getopt_long (argc, argv, "abc:d:", long_options, &option_index);
/* Detect the end of the options. */ if (c == -1) break;
switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s/n", optarg); break;
case 'a': puts ("option -a/n"); break;
case 'b': puts ("option -b/n"); break;
/* 可能是-c --creat参数指出来的 */ case 'c': printf ("option -c with value `%s'/n", optarg); break;
case 'd': printf ("option -d with value `%s'/n", optarg); break; } }
exit (0); }
当我们输入了错误的选项后,系统会给出错误的提示,如果我们想屏蔽这个信息,我们可以设置opterr为0,对于错误的选项,函数分析时候返回一个'?'字符.我们可以自己对这个字符进行处理.
 
|