【C】命令行参数解析——getopt、getopt_long及getopt_long_only
前言
在linux下学习开源代码Webbench,遇到get_long等函数的用法,一时有点懵,故想深入了解这类命令行解析函数,并记此博文。
1、getopt
getopt主要用来处理短命令行选项,例如 ./test -v 中的 -v 就是一个短选项。使用该函数需引入头文件<unistd.h>,下面是该函数定义:
int getopt (int ___argc, char *const *___argv, const char *__shortopts);
其中___argc和___argv是main函数中传递的参数个数和内容,__shortopts用来指定可以处理哪些选项,以下为__shortopts的示例:
"a:bc"
该示例表明该程序可以接受3个选项:-a -b -c ,其中a后面的 :表示该选项后面跟一个参数,即如 -a text 的形式,选项后面跟的参数会被保存到optarg变量中。下面是一个使用的示例:
#include <stdio.h>
#include <unistd.h>
void use_getopt(int argc,char **argv){
int ch;
){
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");
}
}
}
int main(int argc,char **argv){
use_getopt(argc,argv);
;
}
执行 ./test -a aa -b -c 输出结果如下:
option a: aa option b: ./test: invalid option -- 'c' unknown option
2、getopt_long
getopt_long支持长选项的命令行解析,所谓长选项即诸如 --help 的形式,使用该函数需要引入头文件<getopt.h>,下面是getopt_long和getopt_long_only的函数原型:
#include <getopt.h>
int getopt_long (int ___argc,
char *const *___argv,
const char *__shortopts,
const struct option *__longopts,
int *__longind);
int getopt_long_only (int ___argc,
char *const *___argv,
const char *__shortopts,
const struct option *__longopts,
int *__longind);
其中___argc,___argv, __shortopts 和 getopt 中的含义一样,下面解释 __longopts 和 __longind.
__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[] = {
{, NULL, 'v'},
{, NULL, 'n'},
{, NULL, 'h'}
};
以上{"version", 0, NULL, 'v'}, version 即为长选项的名称, 即按如下形式 --version,,0 表示该选项后面不带参数,NULL 表示直接将v返回(字符v在ascii码中对应的数值), 即在使用getopt_long遍历到该条选项时,getopt_long 返回值为字符v对应的ascii码值。
__longind表示长选项在__longopts中的位置,例如上面的例子中,version对应的__longind为0,name对应的__longind为1,help对应的__longind为2,该项主要用于调试,一般设为NULL即可。
下面是一个使用示例:
void use_getopt_long(int argc,char **argv){
const char *optstring = "vn:h";
int c;
struct option opts[] = {
{, NULL, 'v'},
{, NULL, 'n'},
{, NULL, 'h'}
};
){
switch(c){
case 'n':
printf("name is %s\n",optarg);
break;
case 'v':
printf("verson is 0.0.1\n");
break;
case 'h':
printf("this is help\n");
break;
case '?':
printf("unknown option\n");
break;
:
printf("the return val is 0\n");
break;
default:
printf("default");
}
}
}
运行程序 ./test --name evenleo --version --help --haha ,结果如下:
name is evenleo verson is 0.0.1 this is help ./test: unrecognized option '--haha' unknown option
当然也可以使用短选项 ./test -n evenleo -v -h,结果如下:
name is evenleo verson is 0.0.1 this is help
将上面的程序进行修改,将struct option中的flag和__longind设为具体值
void use_getopt_long2(int argc, char *argv[]) {
const char *optstring = "vn:h";
int c;
, f_n = -, f_h = -, opt_index = -;
struct option opts[] = {
{, &f_v, 'v'},
{, &f_n, 'n'},
{, &f_h, 'h'}
};
) {
switch(c) {
case 'n':
printf("name is %s\n", optarg);
break;
case 'v':
printf("version is 0.0.1\n");
break;
case 'h':
printf("this is help\n");
break;
case '?':
printf("unknown option\n");
break;
:
printf("f_v is %d \n", f_v);
printf("f_n is %d \n", f_n);
printf("f_h is %d \n", f_h);
break;
default:
printf("------\n");
}
printf("opt_index is %d\n\n", opt_index);
}
}
运行 ./test -name evenleo -version -help,结果如下:
f_v is -1 f_n is 110 f_h is -1 opt_index is 1 f_v is 118 f_n is 110 f_h is -1 opt_index is 0 f_v is 118 f_n is 110 f_h is 104 opt_index is 2
以上结果可以看出,当给flag指定具体的指针后,getopt_long会返回0,并且val的值赋给了flag指向的变量,下面我们用短选项执行一下程序,运行 ./test -n evenleo -v -h ,结果如下:
name is evenleo opt_index is -1 version is 0.0.1 opt_index is -1 this is help opt_index is -1
可以看出使用短选项时getopt_long相当于getopt,flag和__longind不起作用。
3、getopt_long和getopt_long_only区别
下面解释一下 getopt_long 和 getopt_long_only的区别,用use_getopt_long函数 ,运行 ./test -name evenleo -verson -help,结果如下:
name is ame
verson is 0.0.1
./test: invalid option -- 'e'
unknown option
./test: invalid option -- 'r'
unknown option
./test: invalid option -- 's'
unknown option
./test: invalid option -- 'i'
unknown option
./test: invalid option -- 'o'
unknown option
name is -help
可以看出使用短选项标识符 - 指向长选项时,程序还是会按短选项来处理,即一个字符一个字符的解析。下面将函数use_getopt_long做一些更改,即将getopt_long改为getopt_long_only,如下:
void use_getopt_long3(int argc,char **argv){
const char *optstring = "vn:h";
int c;
struct option opts[] = {
{, NULL, 'v'},
{, NULL, 'n'},
{, NULL, 'h'}
};
){
switch(c){
case 'n':
printf("name is %s\n",optarg);
break;
case 'v':
printf("verson is 0.0.1\n");
break;
case 'h':
printf("this is help\n");
break;
case '?':
printf("unknown option\n");
break;
:
printf("the return val is 0\n");
break;
default:
printf("default");
}
}
}
再运行 ./test -name evenleo -version -help,结果如下:
name is evenleo verson is 0.0.1 this is help
即使用 getopt_long_only 时, - 和 -- 都可以作用于长选项, 而使用 getopt_long 时,只有 -- 可以作用于长选项.
文章大部分内容参考http://blog.zhangjikai.com/2016/03/05/%E3%80%90C%E3%80%91%E8%A7%A3%E6%9E%90%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0--getopt%E5%92%8Cgetopt_long/
【C】命令行参数解析——getopt、getopt_long及getopt_long_only的更多相关文章
- Python命令行参数解析模块getopt使用实例
Python命令行参数解析模块getopt使用实例 这篇文章主要介绍了Python命令行参数解析模块getopt使用实例,本文讲解了使用语法格式.短选项参数实例.长选项参数实例等内容,需要的朋友可以参 ...
- python命令行参数解析模块argparse和docopt
http://blog.csdn.net/pipisorry/article/details/53046471 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的o ...
- shell 命令行参数(getopt和getopts)
getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...
- [转]Python 命令行参数和getopt模块详解
FROM : http://www.tuicool.com/articles/jaqQvq 有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Pyt ...
- Python 命令行参数和getopt模块详解
有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Python里,命令行的参数和C语言很类似(因为标准Python是用C语言实现的).在C语言里,m ...
- gflags命令行参数解析
gflags库是google开源的命令行参数解析工具. 安装 官方没有提供二进制库,但是Debian/Ubuntu平台本身提供了二进制库,可以直接git clone https://github.co ...
- [Go] 命令行参数解析包(flag 包)使用详解
Go 的 flag 包可以解析命令行的参数. 一.命令行语法 命令行语法主要有以下几种形式: cmd -flag // 只支持bool类型 cmd -flag=xxx cmd -flag ...
- $命令行参数解析模块argparse的用法
argparse是python内置的命令行参数解析模块,可以用来为程序配置功能丰富的命令行参数,方便使用,本文总结一下其基本用法. 测试脚本 把以下脚本存在argtest.py文件中: # codin ...
- Google开源命令行参数解析库gflags
Google开源命令行参数解析库gflags http://blog.csdn.net/lming_08/article/details/25072899 CMDLINE的解析 http://blog ...
随机推荐
- VUE: 移动端长按弹出确认删除地址(后面测试发现IOS有BUG,后面有更新随笔,更新后的亲测有效)
收货地址的删除方式可能有很多种,我目前见过的暂时只有两种(1.在编辑页删除 2.长按某一条收货地址弹出是否删除地址) 在开发的项目上要求第二种删除方法,于是记录一下我写的代码 ~ 1.首先,在移动端 ...
- php+提高大文件上传速度
PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...
- java+Word图片上传控件
这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用 后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下) ...
- AtCoder AGC038D Unique Path (图论)
题目链接 https://atcoder.jp/contests/agc038/tasks/agc038_d 题解 orz zjr神仙做法 考虑把所有\(C_i=0\)的提示的两点连边,那么连完之后的 ...
- linux 查看内网IP和外网IP
centos7 查看内网的ip,使用ifconfig 或在后面加上参数,都可以查看内网的ip,下面的10.105.33.17 即是内网的ip [root@VM_33_17_centos ~]#ifco ...
- Javascript引擎的单线程机制和setTimeout执行原理阐述
工作中使用setTimeout解决了一个问题,于是对setTimeout的相关资料整理了下,以及对js引擎执行的原理一并整理了下,希望能给码农们一些帮助.若发现有错的地方大家及时指出,共同学习进步. ...
- Swagger : API JSON 文件 转 PDF 问题总结
1. swagger API 转 PDF 具体请参考:woshihoujinxin/swagger-gendoc 2. 问题总结 接口方法值返回值为 void 类型时, @ApiOperation ...
- python接口自动化:pycharm中import yaml报错问题解决
一:问题 python3在cmd命令行中已经安装了yaml,且import yaml是成功的,但是pcharm中import yaml还是红色报错 二:分析原因 pycharm和python环境需要分 ...
- 7 Java 快速排序
快速排序(Quicksort)是对冒泡排序的一种改进. 1.基本思想 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别 ...
- ThinkPhp sql语句执行方法
ThinkPHP内置的ORM和ActiveRecord模式实现了方便的数据存取操作,而且新版增加的连贯操作功能更是让这个数据操作更加清晰,但是ThinkPHP仍然保留了原生的SQL查询和执行操作支持, ...