在Linux c语言开发时,可使用getopt_long获取命令行参数,这个方法同时支持短选项和长选项,比较方便。(因为选项可以带参数,为了不和命令行参数混淆,这里命令行参数称为选项)
边看代码,边做分析:
#include <stdio.h>
#include <getopt.h> //需要包括此头文件
// Values for long options
// 长选项对应的整数值,在long_options结构体数组中,对长选项名对应的整数值进行定义
enum {
LONGOPT_VAL_TIMEOUT = 257, //注意我们定义的值从257开始,是为了避开短选项
LONGOPT_VAL_MPORT
};
// 定义短选项,如果有必选参数就要在选项名后加冒号,无参数或可选参数则不要
// 短选项的用法是一个-后面跟选项名,如果有参数空格加参数,例如 ./myserver -c cfg.json
// 如果是可选参数则要使用两个-,并用等号赋值,例如:./myserver --v=5
static const char *short_options = "c:vh";
// 长选项的用法是两个-后面选项名,如果有参数需要看是必须参数还是可选参数。
// 定义长选项数组,每一项是一个结构体,第一个成员是长选项名,第二个成员是参数使用情况,包括:
// required_argument:必须参数,在命令行中需要跟在选项名后面用空格分开,例如 ./myserver --port 8000 或者用等号连接 ./myserver --port=8000
// no_argument: 没有参数,那么在选项之后就不能写参数,如果用等号加参数就会报错 option '--help' doesn't allow an argument,如果空格加参数,那参数会被认为是一个选项。
// optional_argument: 可选参数,只能使用等号添加。例如 ./myserver --verbose=5
// 结构体第四个成员是选项对应的整数值。值得注意的是,这里长选项的整数值可以填入短选项的字符,这样长短选项可以关联起来,达到相同的效果。如果长选项没有对应可用的短选项,则这儿要定义一个数值,这个数值最好大于256,避免和短选项值冲突。下面会看到getopt_long返回值就是这个数值,通过这个数值进行不同的操作。
static const struct option long_options[] = {
{"port", required_argument, NULL, 'p'},
{"timeout", required_argument, NULL, LONGOPT_VAL_TIMEOUT},
{"config", required_argument, NULL, 'c'},
{"verbose", optional_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
int main(int argc, char *argv[])
{
char *config_file = NULL;
char *port = NULL;
float timeout = 0.0f;
int verbose = 0;
int opt = 0;
while( (opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1){
switch (opt){
case 'h':
case '?': //如果是不能识别的选项,则opt返回'?'
fprintf(stdout, "Usage: %s -p <port> [-v|--v <=verbose_level>] [-h]\n", argv[0]);
return 0;
case 'c':
config_file = optarg;
break;
case 'p': // 'p'是个短选项,但是长选项port的值也是'p',所以这里同时处理了port
port = optarg;
break;
case LONGOPT_VAL_TIMEOUT: //长选项timeout的值
timeout = atof(optarg);
break;
case 'v': // verbose有可选参数,所以这儿判断是否有参数
if(optarg == NULL){
verbose = 1;
}
else {
verbose = atoi(optarg);
}
break;
}
}
return 0;
}
网友评论