欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1.命令行选项解析

程序员文章站 2022-03-17 14:48:57
...


有时候在linux上运行程序的时候,对后面跟着的-h -r --help等等选项的解析方法充满好奇,现在就来了解一下完成这个任务的函数吧。

1.getopt_long()函数

在了解具体函数前我们需要约定一些事情,文章开头-h -r --help虽然都是选项,但是我们需要把它分为两类,分别是双横的长选项--help和一横的短选项-h -r
在这里我们先不考虑长选项,仅仅实现短选项解析的实现,在了解一个函数之前,我们首先要做的就是分析参数返回值。

int getopt_long(int argc, char * const argv[],
				 const char *optstring,
				 const struct option *longopts, int *longindex);

argc和argv不用多说,其实就是main后面的命令行参数。
optstring 这个参数与"短选项"有关,比如我们运行程序时后面接了-h,那么getopt_long函数就会去optstring这个字符串中去匹配是否有h这个字符,如果有,h就会作为函数返回。
longopts 这个参数与"长选项"有关,我们先不考虑这个参数,在下面我们会讲这个option结构体。
longindex 这个参数也是与"长选项"有关。
下面我们用几个例子来讲讲这几个参数具体是啥意思。

	int c;
	int argument;
	while(1){
		// z: 后面:的意思代表z这个选项后面要接参数
		c = getopt_long(argc, argv, "?sz:",
			 	NULL, NULL);
		if(c == -1) //getopt_long会在所有选项解析完之后返回-1
			break;
		switch (c) {
			case '?':
				printf("you need help?\n");
				break;
			case 's':
				printf("my name is szg\n");
				break;
			case 'z':
				//optarg是个全局变量,在每次循环中用来保存选项后面的参数
				argument = atoi(optarg); 
				printf("my name is zec,argument is %d\n",argument);
				break;
			default:
				printf("___________\n");
		}
	}

我们来运行一下程序,看看结果如何。
1.命令行选项解析
我们画个图,看看发生了什么。
1.命令行选项解析

2.option结构体

这里我们提到的option结构体与主要是与"长选项"有关。

struct option {
	const char *name;	//长选项的名字
	int 		has_arg;//长选项是否带参数
	/*
	 *	no_argument (0) 选项不带参数
	 *	required_argument (1) 选项带参数
	 *	optional_argument	(2)	可带可不带
	 */
	
	int 	   *flag;	//与val一起决定getopt_long()返回什么
	/*
	 *	flag为NULL,getopt_long()会返回val
	 *	flag不为NULL,getopt_long()会返回0
	 *			如果找到了选项,flag指向的值会被设置成val	
	 *			如果没找到选项,flag指向的值不变
	 */			
	
	int 		val;
	/*
	 *	The last element of the array has to be filled with 0
	 *	数组最后一个元素必须被填为0
	 */
};

一般情况下flag参数我们都设置为NULL,下面让我们声明一个option数组的例子

static const struct option long_options[]=
{
	{"help",no_argument,NULL,'?'},
    {"szg",no_argument,NULL,'s'},
    {"zec",required_argument,NULL,'z'},
    {NULL,0,NULL,0}
};

getopt_long发现输入的选项是长选项(比如–help),它会去我们定义的这个列表中去寻找,找到了"help",接着getopt_long返回第四个参数val,在我们举的例子中就是问号(?)
我们改造一下上面的函数,在进行测试。

	static const struct option long_options[]=
	{
		{"help",no_argument,NULL,'?'},
	    {"szg",no_argument,NULL,'s'},
	    {"zec",required_argument,NULL,'z'},
	    {NULL,0,NULL,0}
	};
	int c;
	int option_index = 0;
	int argument;
	while(1){
		c = getopt_long(argc, argv, "?sz:",
			 	long_options, &option_index);
		if(c == -1)
			break;
		switch (c) {
			case '?':
				printf("you need help?\n");
				break;
			case 's':
				printf("my name is szg\n");
				break;
			case 'z':
				argument = atoi(optarg);
				printf("my name is zec,argument is %d\n",argument);
				break;
			default:
				printf("___________\n");
		}
	}

1.命令行选项解析