在实际编程当中,自己编写代码处理命令行参数是比较麻烦且易出错的。一般我们会直接使用getopt()getopt_long()函数,下文将介绍具体的使用方法。

getopt()

getopt()用于处理”单字母“选项,如-a, -t等。函数声明如下:

  1. #include <unistd.h>
  2. int getopt(int argc, char *const argv[], const char *optstring);
  3. extern char *optarg;
  4. extern int optind, opterr, optopt;

参数说明

对于前两个参数argcgrgv[],一般直接使用main()传递进来的数值。用过C语言的同学应该比较熟悉,简单复习一下。

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. int main(int argc, char const *argv[])
  4. {
  5. //在C99标准推出之前,变量不能在for()声明,为了兼容性,这里提前声明"i"
  6. int i;
  7. printf("argc = %d\n", argc);
  8. if (argc > 1)
  9. {
  10. for (i = 0; i < argc; ++i)
  11. {
  12. printf("argv[%d] = %s\n", i, argv[i]);
  13. }
  14. }
  15. return 0;
  16. }

argc: argument count, 记录了命令行参数的个数(包括命令本身)

argv: argument vector, 记录了命令行参数的具体内容

  1. $ ./test 1 2 3
  2. argc = 4
  3. argv[0] = ./test
  4. argv[1] = 1
  5. argv[2] = 2
  6. argv[3] = 3

optstring: 作为getopt()的第三个参数,用于规定合法选项(option)以及选项是否带参数(argument)。一般为合法选项字母构成的字符串,如果字母后面带上冒号:就说明该选项必须有参数。如"ht:"说明有两个选项-h-t且后者(-t)必须带有参数(如-t 60)。

返回值

  • option character: 一般情况下,getopt()读取到合法选项,就返回该选项(一个字母)。
  • -1:结束标志。
  1. while ( (opt = getopt(argc, argv, "ab:") ) != -1) {...}
  • ?: 一般情况下,遇到非法选项或者参数缺失都会返回?。如果需要区分这两种错误,可以在optstring开头加上:,如:ht: , 这样参数缺失就返回:非法选项就返回?
  • ::在optstring参数开头第一个字符为:时,遇到参数缺失返回:。参考下方代码(摘自Linux Programming by Example)可帮助理解
  1. int oc; /* option character */
  2. char *b_opt_arg;
  3. while ((oc = getopt(argc, argv, ":ab:")) != -1) {
  4. switch (oc) {
  5. case 'a':
  6. /* handle -a, set a flag, whatever */
  7. break;
  8. case 'b':
  9. /* handle -b, get arg value from optarg */
  10. b_opt_arg = optarg;
  11. break;
  12. case ':':
  13. /* missing option argument 参数缺失*/
  14. fprintf(stderr, "%s: option '-%c' requires an argument\n",
  15. argv[0], optopt);
  16. break;
  17. case '?':
  18. default:
  19. /* invalid option 非法选项*/
  20. fprintf(stderr, "%s: option '-%c' is invalid: ignored\n",
  21. argv[0], optopt);
  22. break;
  23. }
  24. }

相关变量

  • optind(option index): 数组下标,指向下一个未处理的参数。通过例子(摘自stackoverflow)能更好理解:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. int main(int argc, char *argv[])
  5. {
  6. char optStr[] = "ab";
  7. int c;
  8. while ((c = getopt(argc, argv, optStr)) != -1) {
  9. printf("optind: %d\n", optind);
  10. switch (c) {
  11. case 'a':
  12. printf("-a\n");
  13. break;
  14. case 'b':
  15. printf("-b\n");
  16. break;
  17. case '?':
  18. printf("error\n");
  19. break;
  20. }
  21. }
  22. return 0;
  23. }

测试结果:

  1. $ ./a.out -ab #例子1
  2. optind: 1
  3. -a
  4. optind: 2
  5. -b
  6. $ ./a.out -a #例子2
  7. optind: 2
  8. -a

例子1:

  1. #argv[]数据如下
  2. argv[0]="./a.out"
  3. argv[1]="-ab"
  4. argv[2]=0

optind=1开始,处理完aoptind指向b所在位置,其实还是1;处理完b,指向下一个选项,即2

例子2:

  1. #argv[]数据如下
  2. argv[0]="./a.out"
  3. argv[1]="-a"
  4. argv[2]=0

optind=1开始,处理完a,指向下一个选项,即2

  • optarg: 如果合法选项带有参数,那么对应的参数,赋值给optarg

getopt_long()

根据函数名就可以知道getopt_long()用于处理长选项,如-help。函数声明如下:

  1. #include <getopt.h>
  2. int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);

参数说明

前三个选项和getopt()完全相同,在此不再赘述。

  • longopts数组: 用于规定合法长选项以及长选项是否带参数(argument)。涉及到的option结构体声明如下
  1. struct option {
  2. const char *name;
  3. int has_arg;
  4. int *flag;
  5. int val;
  6. };
  1. name: 长选项的名称
  2. has_arg: 参数情况
符号常量 数值 Meaning
no_argument 0 无参数
required_argument 1 有参数
optional_argument 2 参数可选

考虑到“可读性”,一般使用“符号常量”

  1. int *flag: 如果flagNULL, getup_long() 返回val的值; 如果不是NULL, val的值赋给flag指针指向的内容,同时getopt_long()返回 0
  2. int val: flagNULLval作为getopt_long()的返回值;如果flag不为NULLval赋值给flag指针所指内容;
int *flag return value
NULL val
&name(<— val) 0

通过例子(摘自webbench)可加深理解

  1. static const struct option long_options[]=
  2. {
  3. {"force",no_argument,&force,1}, //-force 参数三(flag)不为NULL,force=1,getopt_long()返回0
  4. {"reload",no_argument,&force_reload,1},
  5. {"time",required_argument,NULL,'t'},
  6. {"help",no_argument,NULL,'?'}, //-help 第三个参数(flag)为NULL,直接返回 "?"
  7. {"http09",no_argument,NULL,'9'},
  8. {"http10",no_argument,NULL,'1'},
  9. {"http11",no_argument,NULL,'2'},
  10. {"get",no_argument,&method,METHOD_GET},
  11. {"head",no_argument,&method,METHOD_HEAD},
  12. {"options",no_argument,&method,METHOD_OPTIONS},
  13. {"trace",no_argument,&method,METHOD_TRACE},
  14. {"version",no_argument,NULL,'V'},
  15. {"proxy",required_argument,NULL,'p'},
  16. {"clients",required_argument,NULL,'c'},
  17. {NULL,0,NULL,0} //最后一个元素应该全为0
  18. };
  19. int main(int argc, char *argv[])
  20. {
  21. int options_index=0;
  22. ...
  23. while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
  24. {
  25. ...
  26. }
  27. }

注意: longopts数组最后一个元素应该全为0.

  • longindex: 一般设置为NULL; 如果不为NUll, 指向每次找到的长选项longopts的位置,可以通过该值(即索引)找到当前长选项的具体信息。

希望本文能帮助大家更好地理解getopt()getopt_long()

更多的相关用法可以参考Linux Programming by Example: The Fundamentals

命令行参数处理-getopt()和getopt_long()的更多相关文章

  1. 命令行参数解析函数getopt和getopt_long函数【转】

    原文地址:http://blog.csdn.net/cashey1991/article/details/7942809 getopt和getopt_long函数   平时在写程序时常常需要对命令行参 ...

  2. 【C】命令行参数解析——getopt、getopt_long及getopt_long_only

    前言 在linux下学习开源代码Webbench,遇到get_long等函数的用法,一时有点懵,故想深入了解这类命令行解析函数,并记此博文. 1.getopt getopt主要用来处理短命令行选项,例 ...

  3. [转]Python 命令行参数和getopt模块详解

    FROM : http://www.tuicool.com/articles/jaqQvq 有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Pyt ...

  4. Python 命令行参数和getopt模块详解

    有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Python里,命令行的参数和C语言很类似(因为标准Python是用C语言实现的).在C语言里,m ...

  5. 命令行参数解析函数 getopt

    命令行参数解析函数 —— getopt() getopt()函数声明如下: #include <unistd.h> int getopt(int argc, char * const ar ...

  6. shell 命令行参数(getopt和getopts)

    getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...

  7. 转载:linux编程,命令行参数输入getopt

    下面资料来自百度百科: getopt(分析命令行参数) 相关函数 表头文件 #include<unistd.h> 定义函数 int getopt(int argc,char * const ...

  8. webbench源码学习-->命令行选项解析函数getopt和getopt_long函数

    对于webbench这个网站压力测试工具网上介绍的很多,有深度详解剖析的,对于背景就不在提了, 听说最多可以模拟3万个并发连接去测试网站的负载能力,这里主要是学习了一下它的源码,做点 笔记. 官方介绍 ...

  9. getopt函数的使用——分析命令行参数

    getopt(分析命令行参数) getopt(分析命令行参数) 短参数的定义 返回值 范例 getopt_long 相关函数表头文件#include<unistd.h> 函数声明int g ...

随机推荐

  1. 实战案例--TEMPDB暴涨

    前言   tempdb暴增,造成磁盘空间不足,甚至影响业务运行.     正文   如图,tempdb log文件从7.40开始突然暴涨,因为 tempdb 0 M到 40G     tempdb 所 ...

  2. [iOS开发]Xcode8兼容iOS7以及低版本Xcode调试高版本iOS系统

    现在的项目一般都要兼容iOS7系统,同时也要兼容iOS10,在Xcode8上面,默认情况下无法调试iOS7,因为缺乏调试iOS7需要的配置文件.同时在低版本的Xcode上面(8以下),也无法调试iOS ...

  3. (一)Builder(建造者)模式

    我们一般在构建javabean的对象的时候通常有三种写法: 1.直接通过构造函数传参的方式设置属性,这种方法如果属性过多的话会让构造函数十分臃肿,而且不能灵活的选择只设置某些参数. 2.采用重叠构造区 ...

  4. 自制mpls ldp实验

    实验步骤 步骤1:完成EIGRP BGP 及宣告配置 步骤2:完成LDP 的配置 过程校验 步骤1:校验和理解LDP 邻居关系的发现和邻接关系的建立 R4#show mpls ldp discover ...

  5. Java计算器1.0版

    此版本只是设计了页面,还没有实现事件监听   代码: package com.niit.javagui; import java.awt.Button; import java.awt.FlowLay ...

  6. 201521123024《Java程序设计》第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 注意conve ...

  7. 201521123098 《Java程序设计》第1周学习总结

    1. 本章学习总结 在本章的学习中,我和当初学习C语言一样由"Hello world"入手,初步了解了: 1. *NotePad++*的文件创建和编写*Hello world.ja ...

  8. 201521123004 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 注意: notify()/notifyAll()方法和wait()方法都只能在被声明为synchronized的方 ...

  9. 201521123051《Java程序设计》第十周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  10. 第二部分----CSS的基础语法

    PART-1 CSS的基础常识 一.什么是CSS? W3C标准中,倡导有3:其一为内容与表现分离,其二为内容与行为分离,其三为内容结构的语义化.其倡导中第一条的"表现"指的便可以说 ...