getopt是GNU标准库中的一个小工具,一般只用包含其getopt.h 头文件即可使用。getopt 主要用途是提供一系列方法用户处理基于文字模式(控制台)的C/C++ 应用程序,当然在github上你也可以找到其他语言的版本。getopt 最初并不是标准C或C++ 的一部分,所以只能在每一个编写的应用程序中编译这部分代码,一般包含其头文件,getopt2.c和getopt.c 文件。下面介绍其使用:
在linux 平台下一般都会有glibc 库,其中就包含了getopt,添加其头文件:<getopt.h> 即可,最好再添加一个<unistd.h>。
在windows 平台下,可以使用Mingw32 库,其中也包含了getopt,只要添加<getopt.h> 即可。
可访问的全局变量 (<getopt.h>):
extern int optind; /* 第一个无选项的argv 变量字符串索引 , 初始化为1 */
extern int optopt; /* 保存当前迭代的命令行选项字符串 */
extern int opterr; /* 是否要getopt 将错误信息输出到stderr,初始化为1 */
/* (user may set to zero, to suppress) */
extern char *optarg; /* 指向参数的指针,只有当选项后有接参数时才会有值 */
可调用的函数:
// 基本的处理方法,只支持短选项
extern int getopt(int nargc, char * const *nargv, const char *options);
// 可支持长选项和短选项
extern int getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
// 可支持长选项和短选项,但长选项形式为“-logfile” 而不是 “--logfile”
extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
首先说说Unix 命令行选项,
短选项 | 长选项 | 是否需要参数 | |
-n | --name 具体姓名 | 是(姓名) | 指定用户名 |
-d | --debug | 否 | 是否已测试 |
一般命令行选项分两种, 长选项和短选项,而长选项为了与短选项区分,一般以双短线开头,短选项以一条短线开头,另外选项可以带参数(required_argument),也可以不带参数(no_argument),或者带可选参数(optional_argument)。 要带参数,则在选项后空格填写参数值,如 -n ez, 即是选项-n 参数为 "ez"。
当在Unix或Linux 平台下使用工具时,常常可能会接很长的选项,如gcc 的编译命令: gcc -o main main.c -g
gcc是工具名称,之后的即是选项,选项有两个, -o 带参数 main, -g 不带参数。当然gcc还有更多的选项供使用,为了对每一个参数进行解析,一般使用循环,这也是getopt最常见的使用方法。先说getopt () 的用法,此函数需要传入main 函数的argc 和argv 函数,还要一个字符串,用于表示此应用程序可以接受哪些选项。getopt () 将返回一个int型数字,若当前循环中解析到的选项是此应用程序能读懂的,则这个int数字就是短选项的 ASCII 码。如 当前循环是-o 则getopt () 返回的是 o 字母的 ASCII。但若getopt () 第三个参数字符串中没有指定-o 这个选项,则应用程序无法识别此选项,所以返回的int 为 '?' 的 ASCII。当分析结束时,返回的是-1。
const char* arg_string = "ace:foi";
// 基本的解析循环
while ((arg = getopt (argc, argv, arg_string)) != -1) {
printf ("arg = %d\n", arg);
switch (arg) {
case 'a':
printf ("i find this arg is a\n");
break;
case 'c':
printf ("i find this arg is b\n");
break;
case 'e':
printf ("i find this arg is e, param = %s\n", optarg);
break;
case 'f':
printf ("i find this arg is f\n");
break;
case 'o':
printf ("i find this arg is o\n");
break;
case 'i':
printf ("i find this arg is i\n");
break;
case '?':
printf ("what ??? i do not know this arg option!\n");
break;
default:
printf ("maybe i'll shutdown !!!\n");
exit (1);
}
}
再说说命令行字符串的编写:命令行字符串用来标识此应用程序能接受哪些选项。上面这段代码中选项字符串为 “ace:foi”, 其中每一个字母用来标识一种选项,选项后紧跟冒号用来表示后面必须接一个参数,如果是两个冒号,如 x:: 这种,表示接一个可选参数,即可有可无。上例中e 选项要接一个参数,当解析到有 -e 选项时,其后紧跟的参数就被设置到 optarg 全局变量中。以上就是短选项的使用方法。
若要使用支持长选项的getopt ,则需要使用函数 getopt_long () 或 getopt_long_only ()。先介绍选项的描述结构体,声明在 <getopt.h>:
struct option /* specification for a long form option... */
{
const char *name; /* option name, without leading hyphens */
int has_arg; /* does it take an argument? */
int *flag; /* where to save its status, or NULL */
int val; /* its associated status value */
};
*name : 长选项,不易双短线开头。若长选项为 --file , 则此成员设置为 “file”。
has_arg :是否要携带参数,此成员有三种值,0 —— 2,以枚举方式定义在<getopt.h>
enum /* permitted values for its `has_arg' field... */
{
no_argument = 0, /* option never takes an argument */
required_argument, /* option always requires an argument */
optional_argument /* option may take an argument */
};
no_argument 无参数; required_argument 必须后接参数; optional_argument 可接可不接参数。
*flag :此选项一般用于存放一个内存指针,此内存保存后接的参数值。如 -o main, 则*flag 指向的位置即会填上val 所指向的内容,且getopt_long () 返回0, 若为NULL则一般getopt_long () 返回后面成员val 的值。
const struct option longopts [] = {
{"alpha", no_argument, NULL, 'a'},
{"come", no_argument, NULL, 'c'},
{"edit", no_argument, NULL, 'e'},
{"file", no_argument, NULL, 'f'},
{"option", no_argument, NULL, 'o'},
{"inter", no_argument, NULL, 'i'},
{NULL, 0, NULL, NULL}
};
int arg;
while ((arg = getopt_long (argc, argv, arg_string, longopts, NULL)) != -1) {
switch (arg) {
case 'a':
printf ("i find this arg is a\n");
break;
case 'c':
printf ("i find this arg is b\n");
break;
case 'e':
printf ("i find this arg is e, param = %s\n", optarg);
break;
case 'f':
printf ("i find this arg is f\n");
break;
case 'o':
printf ("i find this arg is o\n");
break;
case 'i':
printf ("i find this arg is i\n");
break;
case '?':
printf ("what ??? i do not know this arg option!\n");
break;
default:
printf ("maybe i'll shutdown !!!\n");
exit (1);
}
}
与getopt () 一样,getopt_long () 返回值大致相同。