在看一个看开源的代码的时候,看到了一个选项参数的操作,里面用到了getopt_long这个函数,发现这个函数真的蛮不错的,对长选项或短选项处理的很好。
1.结构体
struct option
{
const char* name;
int has_arg;
int *flag;
int val;
}
name是长选项的名字,has_arg值为0、1、2,分别表示没有参数、有参数、参数可选,flag如果为NULL,函数返回val的值,否则将val的值写入flag指向的变量中,一般情况下,如果flag为NULL,则val的值为该长选项对应的短选项。或者说
每一个结构体包含4个域,第一个域为长选项字符串(--help),第二个域是一个标识,只能为0、1或2,分别代表没有、有和可选。第三个域永远为NULL。第四个域为对应的短选项字符串(-h)。
例如:
struct option long_options[]={
{ "port", 1, NULL, 'p' },
{ "file", 1, NULL, 'f' },
{ "help", 0, NULL, 'h' },
{ 0, 0, 0, 0},
};
2.一个字符串
这个字符串,包括所需要的短选项字符,如果选项后有参数,字符后加一个":"符号。本文中,这个字符串应该为"p:f:h"。(因为-p -f后面有参数,所以字符后面要加":")
每次调用getopt_long,它会解析一个符号,返回相应的短选项字符,如果解析完毕返回-1。所以需要使用一个循环来处理所有的参数,而相应的循环里会使用switch语句进行选择。如果getopt_long遇到一个无效的选项字符,它会打印一个错误消息并且返回'?',很多程序会打印出帮助信息并且中止运行;当getopt_long解析到一个长选项并且发现后面没有参数则返回':',表示缺乏参数。当处理一个参数时,全局变量optarg指向下一个要处理的变量。当getopt_long处理完所有的选项后,全局变量optind指向第一个未知的选项索引。
示例代码:
#include<stdio.h>
#include<getopt.h>
char *l_opt_arg;
char *const short_options="p:f:h";
struct option long_options[]={
{ "port", 1, NULL, 'p' },
{ "file", 1, NULL, 'f' },
{ "help", 0, NULL, 'h' },
{ 0, 0, 0, 0},
};
int main(int argc,char *argv[])
{
int c;
int option_index=0;
while((c = getopt_long (argc, argv, short_options, long_options, &option_index)) != -1)
{
switch (c){
case 'p':
l_opt_arg = optarg;
printf("the port is %s\n",l_opt_arg);
break;
case 'f':
l_opt_arg = optarg;
printf("the file name is %s\n",l_opt_arg);
break;
case 'h':
printf("./getopt_long [option] ... file ...\n");
printf("-p, --port set the port \n");
printf("-f, --file set the file will be sent\n");
printf("-h, --help for more help\n");
break;
default:
break;
}
}
return 0;
}