之前自己查找了很多资料都不能理解是什么意思,这里我将简明的介绍这两个函数的用法,如果对具体的感到厌倦,可以将这两个函数当作tool使用,只要知道是这么用就ok了。
linux中,经常需要各种命令,通常情况下都会带各种参数
例如 ls -a 就是把包括隐藏文件在内的所有文件显示出来,这里的-a就叫做短选项
又如vim --version 就是把当前vim的版本显示出来,这里的–version就是长选项
接下来将详细讲解如何实现命令行参数解析功能相关的两个函数
getopt()和getopt_long()
getopt()
- 函数原型
#include<unistd.h>
int getopt(int argc, char* const argv[ ], const char *optstring )
- 函数功能:用来解析命令行参数,参数argc和argv分别代表参数个数和内容,跟main()函数里的命令行参数一样
- 参数:
第三个参数optstring: 为选项字符串,告知getopt可以处理那个选项以及哪个选项需要参数,如果选项字符串里的字母后接着冒号:“:”,则表示还有相关的参数,全域变量optarg即会指向此额外参数,
如果在处理期间遇到了不符合optstring指定的其他选项,getopt()将会显示一个错误消息,并将全局域变量设置为“?”字符,将全局域变量opterr设置为0则将不会打印出错信息。
例如
#include <stdio.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int ch;
opterr = 0;//不打印错误信息
while( ( ch = getopt(argc,argv,"tl:q::") ) != -1 )
{
switch(ch)
{
//第一个参数t后面不跟参数
case 't': printf("this is ttt\n");break;
//第二个参数l后面要跟参数执行命令并打印参数
case 'l': printf("this is lll: %s\n",optarg); break;
//第三个参数q后面可跟可不跟参数,一个参数的话必须紧跟q后面不能有空格
case 'q': printf("this is qqq: %s\n",optarg); break;
default: printf("other option :%c\n",ch);
}
}
return 0;
}
- 运行演示
因为getopt()函数不带长选项,在项目中我们一般使用getopt_long()函数
getopt_long()
getopt_long是getopt的泛集,
getopt是getopt_long的一个子集,getopt支持的所有特性,getopt_long都支持,包括错误打印、argv元素顺序调整等;
getopt_long相比getopt增加了长选项的解析
- 函数原型
#include <getopt.h>
extern char *optarg;
extern int optind, opterr, optopt;
//参数optarg:指向当前选项参数的指针
//参数optind:再次调用getopt_long时的下一个argv指针索引
//参数optopt:表示最后一个未知选项
//如果opterr = 0,在getopt、getopt_long、getopt_long_only遇到错误将不会输出错误信息到标准输出流。opterr在非0时,向屏幕输出错误。
int getopt_long(
int argc,
char *const argv[],
const char *optstring, //这个参数和getopt()相应的参数一样,表示短选项字符串
const struct option *longopts, //表示长选项结构体,指向一个结构体,结构体下面列出。
int *longindex // 表示当前长参数在longopts中的索引值
);
- getopt_long()第三个参数结构体
struct option
{
const char *name; //表示的是长参数名
int has_arg; //是否带参数或可选参数,这个值在getopt.h中有宏定义,如下:
// # define no_argument 0 表示不用跟参数
// # define required_argument 1 表示该参数后面一定要跟个参数值
// # define optional_argument 2 表示可跟 可不跟
int *flag; //确定函数返回值的情况,如果flag是null(通常情况),则函数会返回与该项option匹配的 val值;如果flag不是NULL,则将val值赋予flag所指向的内存,并且返回值设置为0。
int val; //设置为返回值,或者是flag指向的变量;这里要注意不要写-1到val,否则其作用是getopt_long返回-1,然后停止解析选项;
};
- 下面给出项目中的示例代码
int main(int argc, char *argv[])
{
struct option opts[] =
{
{"port", required_argument, NULL, 'p'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0} //这个是固定好的
};
while( (ch=getopt_long(argc, argv, "p:h", opts, NULL)) != -1 )
{
switch(ch)
{
case 'p':
port=atoi(optarg); //如果-p 后面加了参数optarg,就会将这个字符串参数转变成整数,然后复制给这段代码中的port变量
break;
case 'h':
print_helpmsg(argv[0]); //如果执行代码的时候加了-h的选项,就会调用打印帮助信息的函数
return 0;
}
}
}
getopt_long_only()
另外还有一个getopt_long_only()函数
getopt_long_only与getopt_long的区别在于:
getopt_long仅仅只能将"–“开始的选项视为长选项,但getopt_long_only将”-“开头选项也会视为长选项,当长选项列表均不满足时,且短选项满足时,”-"才会解析为短选项;