getopt为解析命令行参数函数,它是Linux C库函数。使用此函数需要包含系统头文件unistd.h。

getopt函数声明如下:

int getopt(int argc, char * const argv[], const char * optstring);

其中函数的argc和argv参数通常直接从main的参数直接传递而来。optstring是一个包含合法选项字符的字符串。如果字符后跟一个冒号”:”,则该选项要求有参数。在argv中以“-“开头的都视作选项,“-“后的字符是选项字符。getopt会返回在argv中的选项字符,此字符会对应optstring中的字符。如果getopt被重复调用,它返回下一个选项字符。如果不再有可识别的选项字符,将返回-1。

如果getopt找到另一个选项字符,则返回该字符,更新外部变量optind和静态变量nextchar,以便下次调用getopt可以重复使用接下来的选项字符。如果成功找到选项,getopt返回该选项字符。如果所有命令行选项已被解析,getopt返回-1.如果getopt遇到一个选项字符不在optstring中,那么将返回"?".

如果getopt遇到一个缺少参数的选项,则返回值取决于optstring中的第一个字符,如果是":",则返回":",否则返回"?".

默认情况下,getopt会调换argv中的内容,将非选项放在最后。这样当getopts读取完所有的选项以后,optind会指向非选项的参数。

在处理选项列表时,getopt可以检测两种错误:(1).一个选项字符在optstring中并没有指定;(2).缺少选项参数。默认情况下,getopt在标准错误上输出错误信息,将错误的选项字符放在optopt中,并返回"?"作为函数结果。如果调用者将全局变量opterr设置为0,那么getopt不会输出错误信息(默认情况下,opterr是一个非零值)。如果optstring中的第一个字符是冒号":",那时getopt同样不会打印错误信息。另外,getopt将返回":"代替返回"?"以表示缺少选项参数。

getopt()所设置的全局变量包括:

(1). char *optarg:当前选项的参数。

(2). int optind: 是在argv中要处理的下一个元素的索引。系统初始化此值为1.调用者可以将其重置为1以重新开始扫描相同的argv,或扫描一个新的参数向量。每次调用getopt时,optind保存下个参数在argv中的索引(index)。如果找到一个选项,getopt会返回找到的选项字符,更新optind。如果选项有参数,将参数存到optarg,否则optarg为0。

(3). int opterr: 这个变量为非零时,getopt为”无效选项”或”缺少参数选项”输出错误信息。

(4). int optopt: 当发现无效选项字符时,getopt或返回'?'字符,或返回':'字符,并且optopt包含了所发现的无效选项字符。

getopt定义分为三种:

(1). 不带参数的选项。

(2). 必须带参数的选项:在选项后加一个冒号。

(3). 可选参数的选项:在选项后加两个冒号。

注意事项:

(1). 不带参数的选项可用连写。

(2). 选项不分先后顺序。

(3). 可选参数的选项与参数之间不能有空格。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

CMakeLists.txt文件内容如下:

PROJECT(samples_cplusplus)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)# 支持C++11
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2 -std=c11")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -g -Wall -O2 -std=c++11")INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})FILE(GLOB samples ${PROJECT_SOURCE_DIR}/*.cpp)FOREACH (sample ${samples})STRING(REGEX MATCH "[^/]+$" sample_file ${sample})STRING(REPLACE ".cpp" "" sample_basename ${sample_file})ADD_EXECUTABLE(test_${sample_basename} ${sample})TARGET_LINK_LIBRARIES(test_${sample_basename} pthread)
ENDFOREACH()

sample_getopt.cpp内容如下:

#include <iostream>
#include <unistd.h>namespace {void test1(int argc, char* argv[])
{// reference: http://man7.org/linux/man-pages/man3/getopt.3.htmlint flags = 0, opt = -1, nsecs = 0, tfnd = 0;while ((opt = getopt(argc, argv, "nt:")) != -1) {switch (opt) {case 'n':flags =1;break;case 't':nsecs = atoi(optarg);tfnd = 1;break;default:fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n", argv[0]);exit(EXIT_FAILURE);}}fprintf(stdout, "flags = %d; tfnd = %d; nsec = %d; optind = %d\n", flags, tfnd, nsecs, optind);if (optind >= argc) {fprintf(stderr, "Expected argument after options\n");exit(EXIT_FAILURE);}fprintf(stdout, "name argument = %s\n", argv[optind]);exit(EXIT_SUCCESS);
}int test2()
{// reference: https://stackoverflow.com/questions/10502516/how-to-call-correctly-getopt-functionconst char* argv[] = {"ProgramNameHere", "-f", "input.gmn", "-output.jpg"};int argc = sizeof(argv) / sizeof(argv[0]);std::cout<<"argc: "<<argc<<std::endl;for (int i = 0; i < argc; ++i) {//std::cout<<"argv: "<<argv[i]<<std::endl;}int c = -1;while ((c = getopt(argc, (char**)argv, "f:s:o:pw:h:z:t:d:a:b:?")) != -1) {std::cout<<"Option: "<<(char)c;if (optarg) {std::cout<<", argument: "<<optarg;}std::cout<<"\n";}return 0;
}int test3(int argc, char* argv[])
{// reference: https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html// Normally, getopt is called in a loop. When getopt returns -1, indicating no more options are present, the loop terminates.// A switch statement is used to dispatch on the return value from getopt. In typical use, each case just sets a variable that is used later in the program.// A second loop is used to process the remaining non-option arguments.int aflag = 0, bflag = 0, index = -1, c = -1;char* cvalue = nullptr;opterr = 0;while ((c = getopt(argc, argv, "abc:")) != -1) {switch (c) {case 'a':aflag = 1;break;case 'b':bflag = 1;break;case 'c':cvalue = optarg;break;case '?':if (optopt == 'c')fprintf(stderr, "Option -%c requires an argument.\n", optopt);else if (isprint(optopt))fprintf(stderr, "Unknown option '-%c'.\n", optopt);elsefprintf(stderr, "Unknown option character '\\x%x'.\n", optopt);return 1;default:abort();}}      fprintf(stdout, "aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue);for (index = optind; index < argc; ++index) {fprintf(stdout, "index: %d, Non-option argument: %s\n", index, argv[index]);}return 0;
}} // namespaceint main(int argc, char* argv[])
{if (argc < 2) {fprintf(stderr, "the number of params must be greater than or equal to 2\n");return -1;}int flag = atoi(argv[1]);switch(flag) {case 1:fprintf(stdout, "start test 1:\n");test1(argc, argv);break;case 2:fprintf(stdout, "start test 2:\n");test2();break;case 3:fprintf(stdout, "start test 3:\n");test3(argc, argv);break;default:fprintf(stderr, "params error\n");break;}return 0;
}

build.sh内容如下:

#! /bin/bashreal_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"new_dir_name=${dir_name}/build
mkdir -p ${new_dir_name}
cd ${new_dir_name}
cmake ..
makecd -

run_getopt.sh内容如下:

#! /bin/bashreal_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"echo "test1:"
${dir_name}/build/test_sample_getopt 9 # params error
${dir_name}/build/test_sample_getopt 1 # flags = 0; tfnd = 0; nsec = 0; optind = 1
${dir_name}/build/test_sample_getopt 1 -b # invalid option -- 'b'
${dir_name}/build/test_sample_getopt 1 -x YYY # invalid option -- 'x'
${dir_name}/build/test_sample_getopt 1 -vZZZ # invalid option -- 'v'
${dir_name}/build/test_sample_getopt 1 -t 999 -n Jim # flags = 1; tfnd = 1; nsec = 999; optind = 4
${dir_name}/build/test_sample_getopt 1 -t888 -nSom # invalid option -- 'S'
${dir_name}/build/test_sample_getopt 1 -t6666 # flags = 0; tfnd = 1; nsec = 6666; optind = 2
${dir_name}/build/test_sample_getopt 1 -nant -t555 # invalid option -- 'a'
${dir_name}/build/test_sample_getopt 1 -n222 -t111 # invalid option -- '2'echo -e "\n\ntest2:"
${dir_name}/build/test_sample_getopt 2
# argc: 4
# Option: f, argument: input.gmn
# Option: o, argument: utput.jpgecho -e "\n\ntest3:"
${dir_name}/build/test_sample_getopt 3
# aflag = 0, bflag = 0, cvalue = (null)
# index: 1, Non-option argument: 3
${dir_name}/build/test_sample_getopt 3 -a -b
# aflag = 1, bflag = 1, cvalue = (null)
# index: 3, Non-option argument: 3
${dir_name}/build/test_sample_getopt 3 -ab
# aflag = 1, bflag = 1, cvalue = (null)
# iindex: 2, Non-option argument: 3
${dir_name}/build/test_sample_getopt 3 -c foo
# aflag = 0, bflag = 0, cvalue = foo
# index: 3, Non-option argument: 3
${dir_name}/build/test_sample_getopt 3 -cfoo
# aflag = 0, bflag = 0, cvalue = foo
# index: 2, Non-option argument: 3
${dir_name}/build/test_sample_getopt 3 arg1
# aflag = 0, bflag = 0, cvalue = (null)
# index: 1, Non-option argument: 3
# index: 2, Non-option argumnet: arg1
${dir_name}/build/test_sample_getopt 3 -a arg1
# aflag = 1, bflag = 0, cvalue = (null)
# index: 2, Non-option argument: 3
# index: 3, Non-option argument: arg1
${dir_name}/build/test_sample_getopt 3 -c foo arg1
# aflag = 0, bflag = 0, cvalue = foo
# index: 3, Non-option argument: 3
# index: 4, Non-option argument: arg1
${dir_name}/build/test_sample_getopt 3 -a -- -b
# aflag = 1, bflag = 0, cvalue = (null)
# index: 3, Non-option argument: 3
# index: 4, Non-option argument: -b
${dir_name}/build/test_sample_getopt 3 -a -
# aflag = 1, bflag = 0, cvalue = (null)
# index: 2, Non-option argument: 3
# index: 3, Non-option argument: -

执行过程:首先执行build.sh,然后再执行run_getopt.sh即可。

GitHub: https://github.com/fengbingchun/Linux_Code_Test

Linux下getopt函数的使用相关推荐

  1. [转载]Linux下getopt()函数的简单使用

    转载源地址:https://www.cnblogs.com/qingergege/p/5914218.html 1.getopt()函数的出处就是unistd.h头文件(哈哈),写代码的时候千万不要忘 ...

  2. Linux下getopt()函数的简单使用

    https://www.cnblogs.com/qingergege/p/5914218.html

  3. linux下syscall函数,SYS_gettid,SYS_tgkill

    出处:http://blog.chinaunix.net/uid-28458801-id-4630215.html linux下syscall函数,SYS_gettid,SYS_tgkill 2014 ...

  4. linux下system函数的深入理解

    这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...

  5. Linux下curses函数库的详细介绍

    Linux下curses函数库的详细介绍 curses库介绍 安装 curses库函数介绍 初始化和重置函数 管理屏幕的函数 输出到屏幕 从屏幕读取 清除屏幕 移动光标 字符属性 管理键盘的函数 键盘 ...

  6. linux下readlink函数详解

    linux下readlink函数详解 相关函数: stat, lstat, symlink 表头文件: #include <unistd.h> 定义函数:int  readlink(con ...

  7. linux 纪元时间转换,[转]Linux下时间函数time gettimeofday

    Linux下时间函数time & gettimeofday UNIX及Linux的时间系统是由「新纪元时间」Epoch开始计算起,单位为秒.Epoch是指定为1970年1月1日凌晨零点零分零秒 ...

  8. Linux下connect函数 阻塞 与 非阻塞 问题

    一.概述 linux系统下,connect函数是阻塞的,阻塞时间的长度与系统相关.而如果把套接字设置成非阻塞,调用connect函数时会报错Operation now in progress,且err ...

  9. Linux下select函数实现的聊天服务器

    转载: http://blog.csdn.net/microtong/article/details/4989902 Linux下select函数实现的聊天服务器  佟强 http://blog.cs ...

最新文章

  1. 为保障处理器平稳运行请“三知”cpu
  2. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互
  3. 使用windbg定位内存问题【入门级】
  4. Discuz在线升级中的SC和TC分别是什么意思?
  5. matlab plot title 包含变量的图片标题
  6. 无限极分类中递归查找一个树结构
  7. c++ mmap写入速度_Linux系统编程_用mmap+数组的方式修改数据文件
  8. javascript 西瓜一期 13 十六进制的数数方式与进位
  9. SiriKit 描述
  10. html搜题软件,大学搜题app哪个好_大学好的搜题软件_大学搜题免费
  11. python能做什么-学了Python都能做什么
  12. 2017百度之星初赛:B-1001. Chess
  13. c语言图书管理系统课设报告总结,c语言图书管理系统课设报告.docx
  14. 服装DOCAD度卡系统8.5版本(DOCAD)
  15. Mysql 常用函数集
  16. selenium调用浏览器打印功能,并保存为PDF
  17. vmware fusion8 序列号
  18. 天行健,君子以自强不息 ;地势坤,君子以厚德载物
  19. 二进制十进制小数转换
  20. 171025_matlab_imag函数

热门文章

  1. 优达学城《DeepLearning》2-5:风格迁移
  2. C语言会出现的错误,c语言,能运行但是偶尔会出现些错误,请高手们帮忙看看错在哪里啦...
  3. 光耦p621引脚图_开关电源中光耦电路的设计与优点
  4. 《概率机器人》速度运动模型gmapping中代码解析
  5. Hololens2-OpenXR开发(一)-入门
  6. JavaScript的Array一些非常规玩法
  7. 如何让vue项目打包出来之后更加小巧?
  8. Nginx负载均衡的详细配置及使用案例
  9. Window7 安装开源swf反编译软件JPEXS Free Flash Decompiler(FFdec)实录
  10. UE4风格化场景设计入门指南 Stylized Station – The Environment Artist’s Survival Kit