如何解析命令行参数——getopt与getopt_long


编程新人都知道通过main函数后面的两个参数就能获得命令行的参数,但是接下来事情就比较恼火了。如何方便,快捷的解析这些参数?曾几何时,学生们都是自己写解析函数,来解析这些命令行,如果一个应用有很多很多命令行。那么自己写的函数光测试就要花不少时间。


今天说说两个常见的命令行解析函数getopt和getopt_long。

这两个函数有什么区别呢?

很简单:

if (你有长命令行参数)

use getopt_long

else

use getopt or getopt_long all OK


那什么是短命令行参数,什么是长命令行参数呢?

很简单,只有一个‘-’和一个字母的就是短命令行参数。

有一个'--'再外加几个字母的就是长命令行参数。


比如:--help,--path就是长命令行。 -h,-l就是短命令行参数。


这两个函数的头文件都是,函数原型如下:

int getopt(int argc, char *const argv[], const char *optstring);


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


我们先聊聊getopt,这个函数很简单,前两个参数来自main函数。第三个参数的字符串指出需要匹配的参数字母,如果我的参数有参数值,那么需要在参数字母后面接':'号。比如我的参数有-h和-p,其中p有参数值,那么这个字符串就是 "p:h"


假如我有个应用,这个应用有两个参数,一个是-h,打印help信息,一个是-p接收一个路径字符串。那么代码如下:


while ((c = getopt(argc, argv, "p:h")) != -1) {
    switch(c) {
		case 'h':
			print_help();
			exit(0);
		case 'p':
			parse_path(optarg);
			break;
		default:
			print_help();
			exit(0);
	}
}

注意那个optarg就是参数值的字符串,这个optarg的声明是:

extern char *optarg;

直接用就行,不需要自己再声明了!


接下来来到getopt_long,这个函数多了2个参数,其中一个是一个结构体数组。这个结构体如下:


 struct option {
              const char *name;
              int has_arg;
              int *flag;
              int val;
          };


第一个参数为长命令的全称,比如我有两个参数,一个是"help",一个是"path",那么这里name就指的是这两个字符串。每个参数一个option结构体。还有需要注意的是,长命令必须是“--”开头的,比如“--help,--path”!


第二个has_arg表示该参数是否有参数值,0为没有,1为有且必须,2为有且可选。


第三个flag指针如果为NULL,则getopt_long返回值为后面val这个参数。

如果不为NULL,则会使该指针指向的结构填充为val的值,并让getopt_long返回0。


getopt_long的最后一个参数一般设为NULL就可以了。


假如我的应用有两个参数,一个h或help表示打印帮助信息,一个p或path解析路径。那么程序就这样写:


static struct optiont lopts[] = {
	{"help", 0, 0, 0},
	{"path", 1, 0, 0},
};

while ((opt = getopt_long(argc, argv, "p:h", lopts, &option_index)) != -1)
{
	switch(opt) {
		case 'h':
			print_help();
			exit(0);
		case 'p':
			parse_path(optarg);
			break;
		case 0:
			if (!strcmp(lopts[option_index].name, "help")) {
				printf_help();
				exit(0);
			}
			else if (!strcmp(lopts[option_index].name, "path")) {
				parse_path(optarg);
				break;
			}
			break;
		default:
			print_help();
			exit(0);
	}
} 









你可能感兴趣的:(Linux编程)