Unix编程之getopt getopt_long的使用
最近在看goaccess源码时候,没想到一开头就被getopt_long这个函数给卡住了。。。不禁感慨自己离大牛的差距真是太大了,没办法,慢慢学习积累,希望自己的坚持早晚能导致自己的质变吧。
百度的时候发现了还有getopt这个函数,算是简化版本吧,只支持单字符的命令解析,做linux大型软件开发通常都离不开用户命令参数,下面就来把自己今晚所学到的小小知识点记录下来,以后也能让自己的代码越写越棒!
getopt
以下是摘自manpage中对getopt函数相关参数以及相关变量的展示,接下来对每个参数以及变量进行说明一下
1
2
3
4
5
6
7
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;argc、argv这两个参数是c语言程序运行的参数变量,通过main函数传递进来,argc代表参数个数,argv是字符串参数数组
- optstring这个参数是getopt函数所依赖的参数解释字符串,规则是:字符串中的单独一个字符代表了命令行传递的一个参数,字符后面如果没有冒号,则代表此参数没有对应值,如果有一个或者两个冒号,代表了参数后面有值,一个冒号支持两种传递参数值的方法,值紧挨着参数或者与参数隔一个空格,如果有两个冒号,仅支持紧挨着的写法,比如 “ab:c::d”这个字符串:
- a参数后面没有任何值
- b参数后面有值,可以通过 -b100或者-b 100方式传递
- c参数后面有值,只可以通过 -c100的方式传递
- d参数后面没有任何值
- optarg这是一个char型指针,指向当前参数的值
- optind是下一个argv的索引
- optopt 不知道什么作用….
- opterr如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。
- getopt返回值,如果有参数为当前参数字符,没有参数返回-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(int argc,char *argv[]){
char opt;
const char *optstring = "ab:c::d";
while((opt = getopt(argc,argv,optstring)) != -1){
printf("%c:%s\t",opt,optarg);
printf("optind=%d\t",optind);
printf("next opt is %s\t",argv[optind]);
printf("optopt:%d\n",optopt);
}
return 0;
}
编译之后运行效果如下:1
2
3
4
5./app -a -b 200 -c100 -d
a:(null) optind=2 next opt is -b optopt:0
b:200 optind=4 next opt is -c100 optopt:0
c:100 optind=5 next opt is -d optopt:0
d:(null) optind=6 next opt is (null) optopt:0
以上就是getopt的大致用法
getopt_long
getopt_long保留了getopt的用法,并且支持长参数,就是不是单个字符的选项参数1
2
3
4
5
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
- 前三个参数和getopt基本上一致
- longopts:长参数的结构体配置
- longindex:如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值
- 返回值:对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数
struct option
1
2
3
4
5
6struct option {
const char *name; /* 参数名称 */
int has_arg; /* 指明是否带有参数 */
int *flag; /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值*/
};has_arg取值
1
2
3no_argument 表明长选项不带参数,如:--name, --help
required_argument 表明长选项必须带参数,如:--prefix /root或 --prefix=/root
optional_argument 表明长选项的参数是可选的,如:--help或 –prefix=/root,其它都是错误下面通过实例代码演示用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(int argc,char *argv[]){
int o,idx = 0;
const char *short_opts = "abc";
struct option long_opts[] = {
{"help",no_argument,NULL,'h'},
{"ip",optional_argument,NULL,'i'},
{"port",required_argument,NULL,'p'},
{NULL,0,NULL,0}
};
while((o = getopt_long(argc,argv,short_opts,long_opts,&idx)) != -1){
printf("%c:%s\t",o,optarg);
printf("optind=%d\t",optind);
printf("next opt is %s\n",argv[optind]);
}
return 0;
}
结果1
2
3
4
5./app --help --port=8800 --ip=127.0.0.1
h:(null) optind=2 next opt is --port=8800
p:8800 optind=3 next opt is --ip=127.0.0.1
i:127.0.0.1 optind=4 next opt is (null)