/* * arg.c * * Created on: Jul 21, 2013 * Author: root */ #include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { int i; for(i=0;i<argc;i++) { if(*argv[i]=='-') { printf("option:%s\n",argv[i]+1); } else { printf("argument %d:%s\n",i,argv[i]); } } return 0; }
如果对二级指针 指针数组 二维数组之间的关系不太清楚的话,请查阅C语言程序设计(谭浩强版)第三版 第八章
编译运行:
[root@localhost C_test]# ./arg -i -ldf 'yao' -f yao.c argument 0:./arg option:i option:ldf argument 3:yao option:f argument 5:yao.c
发现-ldf没有像-l -d -f那样处理,这时就要用到getopt函数了。
getopt
函数原型:int getopt(int argc ,char * const * argv,const char * optstring)
extern char * optarg
extern int optind,opterr,optopt
getopt函数将传递给程序的main函数的argc argv作为参数,同时接受一个选项制定符字符串optstring,该字符串告诉getopt哪些选项可用。optstring只是一个字符列表,每个字符代表一个单字符选项。如果一个字符后面紧跟一个冒号,则该选项有一个关联值作为下一个参数。
getopt处理过程:
1 如果选项有一个关联值,则外部变量optarg指向这个值
2 如果选项处理完毕,getopt返回-1,特殊参数--将使getopt停止扫描选项
3 如果遇到一个无法识别的选项,getopt返回一个问号?,并把它保存到外部变量optopt中。
4 如果一个选项要求有一个关联值,但用户并未提供这个值,getopt通常返回一个问号?.如果我们将选项字符串的第一个字符设置为冒号:,那么getopt在用户未提供值的情况下返回冒号:而不是问号?。
外部变量optind为下一个待处理参数的索引,getopt利用它来记录自己的进度。当所有选项参数都处理完毕后,optind将指向argv数组尾部可以找到其余参数的位置,根据POSIX规范的规定,如果opterr是非零值,getopt就会向stderr打印一条错误信息。
/* * argopt.c * * Created on: Jul 21, 2013 * Author: root */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int opt; while((opt=getopt(argc,argv,":if:lr"))!=-1) { switch(opt) { case 'i': case 'l': case 'r': printf("option:%c\n",opt); break; case 'f': printf("filename:%s\n",optarg); break; case ':': printf("option needs a value\n"); break; case '?': printf("unknown option:%c\n",optopt); break; } } for(;optind<argc;optind++) { printf("argument:%s\n",argv[optind]); } return 0; }
编译运行:
[root@localhost C_test]# ./argopt -i -lr 'yaobing' -f hello.c -e option:i option:l option:r filename:hello.c unknown option:e argument:yaobing
[root@localhost C_test]# ./argopt -l -f option:l option needs a value
这样对比下,是不是更清楚了!
getopt_long
是getopt的另一个版本,可以接受双划线(--)开始的长参数
getopt_long在getopt.h头文件中
函数原型:
int getopt_long(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex);
option结构体原型:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
结构中的变量解释:
const char *name:选项名,前面不带-的
int has_arg:长选项是否有选项参数,有三种类型(常量),如下
no_argument(值为0 代表选项没有参数)
required_argument(值为1 代表选项需要参数)
optional_argument(值为2 代表选项参数是可选的)
int *flag:
如果该指针为NULL,那么getopt_long返回val字段的值;
如果该指针不为NULL,那么会使得它所指向的结构填入val字段的值,同时getopt_long返回0
int val:
如果flag是NULL,那么val通常是个字符常量,如果短选项和长选项一致,那么该字符就应该与optstring中
出现的这个选项的参数相同;
最后一个参数:longindex参数一般赋为NULL即可;如果没有设置为NULL,那么它就指向一个变量,这个变量
会被赋值为寻找到的长选项在longopts中的索引值,这可以用于错误诊断。
/* * getopt_l.c * * Created on: Jul 21, 2013 * Author: root */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <getopt.h> int main(int argc, char **argv) { int opt; char * const short_options=":if:lr"; struct option long_options[]= { {"name",1,NULL,'n'}, }; while((opt=getopt_long(argc,argv,short_options,long_options,NULL))!=-1) { switch(opt) { case 'i': case 'l': case 'r': printf("option is %c\n",opt); break; case 'f': printf("filename is %s\n",optarg); break; case 'n': printf("name:%s\n",optarg); break; case ':': printf("option needs a value!"); break; case '?': printf("unknown option:%c",optopt); break; } } for(;optind<argc;optind++) { printf("arguments:%s",argv[optind]); } return 0; }
和上面代码比较,就多了struct option而已。
运行
[root@localhost C_test]# ./getopt_long -rl -f he.c --name yao option is r option is l filename is he.c name:yao
现在长选项 短选项后跟的参数都可以读取到了 ,可以休息下了!
参考链接:http://blog.163.com/shaohj_1999@126/blog/static/63406851201031425650111/