编程新人都知道通过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);
}
}
extern char *optarg;
直接用就行,不需要自己再声明了!
接下来来到getopt_long,这个函数多了2个参数,其中一个是一个结构体数组。这个结构体如下:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
第二个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);
}
}