命令行参数处理-getopt()和getopt_long()
在实际编程当中,自己编写代码处理命令行参数是比较麻烦且易出错的。一般我们会直接使用getopt()和getopt_long()函数,下文将介绍具体的使用方法。
getopt()
getopt()用于处理”单字母“选项,如-a, -t等。函数声明如下:
#include <unistd.h>
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
参数说明
对于前两个参数argc和grgv[],一般直接使用main()传递进来的数值。用过C语言的同学应该比较熟悉,简单复习一下。
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
//在C99标准推出之前,变量不能在for()声明,为了兼容性,这里提前声明"i"
int i;
printf("argc = %d\n", argc);
if (argc > 1)
{
for (i = 0; i < argc; ++i)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
}
return 0;
}
argc: argument count, 记录了命令行参数的个数(包括命令本身)
argv: argument vector, 记录了命令行参数的具体内容
$ ./test 1 2 3
argc = 4
argv[0] = ./test
argv[1] = 1
argv[2] = 2
argv[3] = 3
optstring: 作为getopt()的第三个参数,用于规定合法选项(option)以及选项是否带参数(argument)。一般为合法选项字母构成的字符串,如果字母后面带上冒号:就说明该选项必须有参数。如"ht:"说明有两个选项-h和-t且后者(-t)必须带有参数(如-t 60)。
返回值
option character: 一般情况下,getopt()读取到合法选项,就返回该选项(一个字母)。-1:结束标志。
while ( (opt = getopt(argc, argv, "ab:") ) != -1) {...}
?: 一般情况下,遇到非法选项或者参数缺失都会返回?。如果需要区分这两种错误,可以在optstring的开头加上:,如:ht:, 这样参数缺失就返回:,非法选项就返回?。::在optstring参数开头第一个字符为:时,遇到参数缺失返回:。参考下方代码(摘自Linux Programming by Example)可帮助理解
int oc; /* option character */
char *b_opt_arg;
while ((oc = getopt(argc, argv, ":ab:")) != -1) {
switch (oc) {
case 'a':
/* handle -a, set a flag, whatever */
break;
case 'b':
/* handle -b, get arg value from optarg */
b_opt_arg = optarg;
break;
case ':':
/* missing option argument 参数缺失*/
fprintf(stderr, "%s: option '-%c' requires an argument\n",
argv[0], optopt);
break;
case '?':
default:
/* invalid option 非法选项*/
fprintf(stderr, "%s: option '-%c' is invalid: ignored\n",
argv[0], optopt);
break;
}
}
相关变量
optind(option index): 数组下标,指向下一个未处理的参数。通过例子(摘自stackoverflow)能更好理解:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char optStr[] = "ab";
int c;
while ((c = getopt(argc, argv, optStr)) != -1) {
printf("optind: %d\n", optind);
switch (c) {
case 'a':
printf("-a\n");
break;
case 'b':
printf("-b\n");
break;
case '?':
printf("error\n");
break;
}
}
return 0;
}
测试结果:
$ ./a.out -ab #例子1
optind: 1
-a
optind: 2
-b
$ ./a.out -a #例子2
optind: 2
-a
例子1:
#argv[]数据如下
argv[0]="./a.out"
argv[1]="-ab"
argv[2]=0
从optind=1开始,处理完a,optind指向b所在位置,其实还是1;处理完b,指向下一个选项,即2
例子2:
#argv[]数据如下
argv[0]="./a.out"
argv[1]="-a"
argv[2]=0
从optind=1开始,处理完a,指向下一个选项,即2
optarg: 如果合法选项带有参数,那么对应的参数,赋值给optarg
getopt_long()
根据函数名就可以知道getopt_long()用于处理长选项,如-help。函数声明如下:
#include <getopt.h>
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
参数说明
前三个选项和getopt()完全相同,在此不再赘述。
longopts数组: 用于规定合法长选项以及长选项是否带参数(argument)。涉及到的option结构体声明如下
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
name: 长选项的名称has_arg: 参数情况
| 符号常量 | 数值 | Meaning |
|---|---|---|
no_argument |
0 |
无参数 |
required_argument |
1 |
有参数 |
optional_argument |
2 |
参数可选 |
考虑到“可读性”,一般使用“符号常量”
int *flag: 如果flag为NULL,getup_long()返回val的值; 如果不是NULL,val的值赋给flag指针指向的内容,同时getopt_long()返回 0int val:flag为NULL,val作为getopt_long()的返回值;如果flag不为NULL,val赋值给flag指针所指内容;
| int *flag | return value |
|---|---|
NULL |
val |
&name(<— val) |
0 |
通过例子(摘自webbench)可加深理解
static const struct option long_options[]=
{
{"force",no_argument,&force,1}, //-force 参数三(flag)不为NULL,force=1,getopt_long()返回0
{"reload",no_argument,&force_reload,1},
{"time",required_argument,NULL,'t'},
{"help",no_argument,NULL,'?'}, //-help 第三个参数(flag)为NULL,直接返回 "?"
{"http09",no_argument,NULL,'9'},
{"http10",no_argument,NULL,'1'},
{"http11",no_argument,NULL,'2'},
{"get",no_argument,&method,METHOD_GET},
{"head",no_argument,&method,METHOD_HEAD},
{"options",no_argument,&method,METHOD_OPTIONS},
{"trace",no_argument,&method,METHOD_TRACE},
{"version",no_argument,NULL,'V'},
{"proxy",required_argument,NULL,'p'},
{"clients",required_argument,NULL,'c'},
{NULL,0,NULL,0} //最后一个元素应该全为0
};
int main(int argc, char *argv[])
{
int options_index=0;
...
while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
{
...
}
}
注意:
longopts数组的最后一个元素应该全为0.
longindex: 一般设置为NULL; 如果不为NUll, 指向每次找到的长选项在longopts的位置,可以通过该值(即索引)找到当前长选项的具体信息。
希望本文能帮助大家更好地理解getopt() 和getopt_long()。
更多的相关用法可以参考Linux Programming by Example: The Fundamentals
命令行参数处理-getopt()和getopt_long()的更多相关文章
- 命令行参数解析函数getopt和getopt_long函数【转】
原文地址:http://blog.csdn.net/cashey1991/article/details/7942809 getopt和getopt_long函数 平时在写程序时常常需要对命令行参 ...
- 【C】命令行参数解析——getopt、getopt_long及getopt_long_only
前言 在linux下学习开源代码Webbench,遇到get_long等函数的用法,一时有点懵,故想深入了解这类命令行解析函数,并记此博文. 1.getopt getopt主要用来处理短命令行选项,例 ...
- [转]Python 命令行参数和getopt模块详解
FROM : http://www.tuicool.com/articles/jaqQvq 有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Pyt ...
- Python 命令行参数和getopt模块详解
有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Python里,命令行的参数和C语言很类似(因为标准Python是用C语言实现的).在C语言里,m ...
- 命令行参数解析函数 getopt
命令行参数解析函数 —— getopt() getopt()函数声明如下: #include <unistd.h> int getopt(int argc, char * const ar ...
- shell 命令行参数(getopt和getopts)
getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...
- 转载:linux编程,命令行参数输入getopt
下面资料来自百度百科: getopt(分析命令行参数) 相关函数 表头文件 #include<unistd.h> 定义函数 int getopt(int argc,char * const ...
- webbench源码学习-->命令行选项解析函数getopt和getopt_long函数
对于webbench这个网站压力测试工具网上介绍的很多,有深度详解剖析的,对于背景就不在提了, 听说最多可以模拟3万个并发连接去测试网站的负载能力,这里主要是学习了一下它的源码,做点 笔记. 官方介绍 ...
- getopt函数的使用——分析命令行参数
getopt(分析命令行参数) getopt(分析命令行参数) 短参数的定义 返回值 范例 getopt_long 相关函数表头文件#include<unistd.h> 函数声明int g ...
随机推荐
- 初识php soap 学习过程中的摘抄,便于后期翻阅
SOAP 简单对象访问协议, webService三要素 , SOAP.WSDL(WebServicesDescriptionLanguage).UDDI(UniversalDescriptionDi ...
- jmeter-fileupload操作使用说明
前言:在http请求过程中上传附件(图片.安装包.视频文件等)虽然基本上Content-Type为:multipart/form-data,但Content-Type也有不一样的,如:图片Conten ...
- MYSQL 中 LIMIT 用法
mapper文件中的sql: ------------------------------------------------------------------------------------- ...
- MPLS LDP随堂笔记2
前一天排错 Acl 1 匹配所有ospf的数据包 (目的 ospf建立邻居关系 传递路由条目) 2 放行UDP报文 让LDP邻居能互相收发HELLO包 4 放行TCP报文 让LDP邻居能够建立TCP会 ...
- lua代码的加载
lua代码的加载 Openresty是什么 OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,通过把lua嵌入到Nginx中,使得我们可以用轻巧的lua语言进行nginx的 ...
- 结对编程1——四则运算-GUI
码市链接:https://coding.net/u/hmhhh/p/hmh-homework/git/tree/master/ 201421123003 黄建英 201421123004 黄美海 题目 ...
- 团队作业8——第二次项目冲刺(Beta阶段)5.18
1.当天站立式会议照片 会议内容: 本次会议为第一次会议 本次会议在陆大楼2楼召开,本次会议内容: ①:部署第二次敏捷冲刺的计划 ②:做第一天任务的详细分工 ③:规定完成时间是在第二天之前 ④:遇到困 ...
- 团队作业4——第一次项目冲刺(Alpha版本)4.22
团队作业4--第一次项目冲刺(Alpha版本) Day one: 会议照片 由于团队中的组员今天不在学校,所以我们的站立会议提前一天展开. 项目进展 由于今天是Alpha版本项目冲刺的第一天,所以没有 ...
- 【Alpha】第一次项目冲刺
今日站立式会议照片 每个人的工作 小组成员 昨天完成的工作 今天计划完成的工作 李志霖 继续访问用户以深入了解他们的需求,分别采用面访,qq等不同方式对意见进行了采集,面访了30个人,qq空间以链接的 ...
- 201521123114 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 Q1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用syn ...