首先使用命令行解析函数getopt与getopt_long函数需要包含如下头文件:
#include <unistd.h>
extern char *optarg; //选项的参数指针
extern int optind, //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。
extern int opterr, //当opterr=0时,getopt不向stderr输出错误信息。
extern int optopt; //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt 中,getopt返回'?’、
int getopt(int argc, char * const argv[], const char *optstring);
int getopt(int argc, char * const argv[], const char * optstring);
其中 argc 和 argv 是main函数中的传递的参数个数和内容, optstring用来指定可以处理哪些选项, 下面是optstring的一个示例:
"a:bc"
该示例表明程序可以接受3个选项: -a -b -c, 其中 a 后面的 :表示该选项后面要跟一个参数, 即如 -a text的形式, 选项后面跟的参数会被保存到 optarg 变量中. 下面是一个使用示例:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
int ch;
while((ch = getopt(argc, argv, "a:b")) != -1) {
switch(ch) {
case 'a':
printf("option a: %s\n", optarg);
break;
case 'b':
printf("option b \n");
break;
case '?': // 输入未定义的选项, 都会将该选项的值变为 ?
printf("unknown option \n");
break;
default:
printf("default \n");
}
}
}
程序输出:
[root c++]#./getopt -a 10 -b
option a: 10
option b
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int opt;
char *optstring = "a:b:c:d";
while ((opt = getopt(argc, argv, optstring)) != -1)
{
printf("opt = %c\n", opt);
printf("optarg = %s\n", optarg);
printf("optind = %d\n", optind);
printf("argv[optind - 1] = %s\n\n", argv[optind - 1]);
}
return 0;
}
程序输出:
[root@centos-linux-10 workspace]# ./getopt -a 1 -b 2 -c 3 -d
opt = a
optarg = 1
optind = 3
argv[optind - 1] = 1
opt = b
optarg = 2
optind = 5
argv[optind - 1] = 2
opt = c
optarg = 3
optind = 7
argv[optind - 1] = 3
opt = d
optarg = (null)
optind = 8
argv[optind - 1] = -d
通过上面的例子能比较清晰看到opt optarg optind等之间对应的关系。
getopt_long支持长选项的命令行解析, 所谓长选项就是诸如--help的形式, 使用该函数, 需要引入
#include <getopt.h>
int getopt_long(int argc,
char * const argv[],
const char *optstring,
const struct option *longopts,
int *longindex);
int getopt_long_only(int argc,
char * const argv[],
const char *optstring,
const struct option *longopts,
int *longindex);
其中 argc , argv , optstring 和getopt中的含义一样, 下面解释一下longopts 和longindex
longopts 指向一个struct option 的数组, 下面是option的定义:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
下面是各字段的含义
name - 长选项的名称, 例如 help
has_arg - 是否带参数, 0 不带参数, 1 必须带参数, 2 参数可选
flag - 指定长选项如何返回结果, 如果flag为NULL, getopt_long() 会返回val. 如果flag不为NULL, getopt_long会返回0, 并且将val的值存储到flag中
val - 将要被getopt_long返回或者存储到flag指向的变量中的值
struct option opts[] = {
{"version", 0, NULL, 'v'},
{"name", 1, NULL, 'n'},
{"help", 0, NULL, 'h'}
};
我们来看{"version", 0, NULL, 'v'}, version 即为长选项的名称, 即按如下形式--version, 0 表示该选项后面不带参数, NULL 表示直接将v返回(字符v在ascii码中对应的数值), 即在使用getopt_long遍历到该条选项时, getopt_long 返回值为字符v对应的ascii码值.
longindex表示长选项在longopts中的位置, 例如在上面的示例中, version 对应的 longindex 为0, name 对应的 longindex 为1, help对应的 longindex 为2, 该项主要用于调试, 一般设为 NULL 即可.
在实际项目中的一个应用:
typedef struct longoption {
int val; /**< equivalent short option char */
const char* name; /**< same as name in 'struct option' */
int has_arg; /**< same as name in 'struct option' */
const char* arg_name; /**< option arg name */
const char* desc; /**< option description, 包含用法和具体的取值 */
} option_t;
option_t mirror_mgt_disablelclmir_opts [] =
{
{'-',0, 0, 0, "Description: "MIRROR_LOCALMIROR_DISABLE_DESC"\n\nUsages:\n "MIRROR_LOCALMIROR_DISABLE_USAGE_SHORT"\n "MIRROR_LOCALMIROR_DISABLE_USAGE_LONG},
{'-',0, 0, 0, "Parameters:"},
{'r', "reserve-lun", LONGOPT_REQUIRE, NULL, " ""Input the LUN's name which will inherit the mirror-pair's mapping attribute"},
{'f', "force", LONGOPT_NOPARAM, NULL, MIRROR_OPTIONAL" "MIRROR_LOCALMIROR_DISABLE_FORCE},
{'h', "help", LONGOPT_NOPARAM, NULL, MIRROR_OPTIONAL" "MIRROR_MGT_HELP},
{'-', 0, 0, 0, "Examples:\n "MIRROR_LOCALMIROR_DISABLE_EXAMPLE},
{0, 0, 0, 0, 0}
};