第一次接触这个函数,是因为学习mjpg-streamer的源码。
函数作用:对命令行选项进行解析。
函数出处
头文件getopt.h中:
#include <getopt.h>
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
参数介绍
optstring:短选项字符串
longopts: struct option数组,用于存放长选项参数
longindex:用于返回长选项在longopts结构体数组的索引值,用于调试;一般置为NULL
先介绍一下struct option
struct option {
const char *name; //长选项名
int has_arg; //是否需要参数
int *flag;
int val;
};
参数has_arg的值:
# define no_argument 0 //if the option does not take an argument
# define required_argument 1 //if the option requires an argument
# define optional_argument 2 //if the option takes an optional argument
参数flag和val相互依赖,主要分两种情况:
(1)flag为NULL,val值用于确定该长选项,所以需要为长选项指定唯一的val值。这里也为长选项和短选项建立了桥梁。
(2)flag不为NULL,则将val值存放到flag所指向的存储空间,用于标识该长选项出现过。
返回值
(1)短选项: 程序中使用短选项,则返回短选项字符(如‘n’),当需要参数时,则在返回之前将参数存入到optarg中。
(2)0/val值: 程序中使用长选项,返回值根据flag和val值确定。
①当flag为NULL时,返回val值(所以根据val值做不同处理,即val必须唯一)。当val值等于短选项值,则可以使用短选项解析函数解析长选项。
②当flag不为NULL时,则将val值存入flag所指向的存储空间,getopt_long_only()返回0
(3)?: 出现未定义的长选项,函数返回“?”
(4)-1: 解析完所有参数之后返回-1(即当函数解析完参数返回-1之后跳出while循环)
实例
实例1:文件getopt.c源码:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h> //getopt_long()头文件位置
int main(int argc, char** argv)
{
const char *optstring = "n:v";
int c, deb, index;
struct option opts[] = {
{"username", required_argument, NULL, 'n'},
{"version", no_argument, NULL, 'v'},
{"debug", no_argument, &deb, 1},
{0,0,0,0}
};
while( (c = getopt_long_only(argc, argv, optstring, opts, &index)) != -1)
{
switch(c)
{
case 'n': //使用-n 或者 --username 指定用户名
printf("username is %s\n",optarg);
break;
case 'v': //使用-v 或者--version,输出版本号
printf("version is 0.0.1 \n");
break;
case 0: //flag不为NULL
printf("debug is %d\n",deb);
break;
case '?': //选项未定义
printf("?\n");
break;
default:
printf("c is %d\n",c);
break;
}
}
return 0;
}
编译运行结果分析:
$ ./getopt -n won
username is won
$ ./getopt -v
version is 0.0.1
$ ./getopt -w
./getopt: unrecognized option '-w'
?
$ ./getopt -d
debug is 1
实例2:文件getopt_1.c源码:(有点问题)
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char** argv)
{
const char *optstring="n:v";
int c,deb,index;
struct option opts[]={
{"username",required_argument,0,0},
{"n",required_argument,0,0},
{"version",no_argument,0,0},
{"v",no_argument,0,0},
{"debug",no_argument,0,0},
{"d",no_argument,0,0},
{"help",no_argument,0,0},
{"h",no_argument,0,0}
};
while((c=getopt_long_only(argc,argv,optstring,opts,&index))!=-1)
{
switch(index){
//-n或者--username
case 0:
case 1:
printf("username:%s\n",optarg);
break;
//-v或者--version
case 2:
case 3:
printf("version:1.0.0\n");
break;
//-d or --debug
case 4:
case 5:
printf("debug:yes\n");
break;
//-h or --help
case 6:
case 7:
printf("Help:?\n");
break;
default:
printf("other:%d\n",index);
break;
}
}
return 0;
}
执行结果分析:
$ ./getopt_1 --username won --version -d -h
username:won
version:1.0.0
debug:yes
Help:?
$ ./getopt_1 -j
Segmentation fault