getopt和getopt_long函数

2023-11-03

平时在写程序时常常需要对命令行参数进行处理,当命令行参数个数较多时,如果按照顺序一个一个定义参数含义很容易造成混乱,而且如果程序只按顺序处理参数的话,一些“可选参数”的功能将很难实现。

在Linux中,我们可以使用getopt、getopt_long、getopt_long_only来对这个问题进行处理。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <unistd.h>  
  2.   
  3. int getopt(int argc, char * const argv[],  
  4.            const char *optstring);  
  5.   
  6. extern char *optarg;  
  7. extern int optind, opterr, optopt;  
  8.   
  9. #include <getopt.h>  
  10.   
  11. int getopt_long(int argc, char * const argv[],  
  12.            const char *optstring,  
  13.            const struct option *longopts, int *longindex);  
  14.   
  15. int getopt_long_only(int argc, char * const argv[],  
  16.            const char *optstring,  
  17.            const struct option *longopts, int *longindex);  


从最简单的getopt讲起,getopt函数的前两个参数,就是main函数的argc和argv,这两者直接传入即可,要考虑的就只剩下第三个参数。

optstring的格式举例说明比较方便,例如:

    char *optstring = "abcd:";

上面这个optstring在传入之后,getopt函数将依次检查命令行是否指定了 -a, -b, -c及 -d(这需要多次调用getopt函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母)

最后一个参数d后面带有冒号,: 表示参数d是可以指定值的,如 -d 100 或 -d user。

optind表示的是下一个将被处理到的参数在argv中的下标值。

如果指定opterr = 0的话,在getopt、getopt_long、getopt_long_only遇到错误将不会输出错误信息到标准输出流。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4.   
  5. int main(int argc, char *argv[])  
  6. {  
  7.     int opt;  
  8.     char *optstring = "a:b:c:d";  
  9.   
  10.     while ((opt = getopt(argc, argv, optstring)) != -1)  
  11.     {  
  12.         printf("opt = %c\n", opt);  
  13.         printf("optarg = %s\n", optarg);  
  14.         printf("optind = %d\n", optind);  
  15.         printf("argv[optind - 1] = %s\n\n",  argv[optind - 1]);  
  16.     }  
  17.   
  18.     return 0;  
  19. }  
编译上述程序并运行,有如下结果:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. cashey@ubuntu:~/Desktop/getopt$ ./test_getopt -a 100 -b 200 -c admin -d  
  2. opt = a  
  3. optarg = 100  
  4. optind = 3  
  5. argv[optind - 1] = 100  
  6.   
  7. opt = b  
  8. optarg = 200  
  9. optind = 5  
  10. argv[optind - 1] = 200  
  11.   
  12. opt = c  
  13. optarg = admin  
  14. optind = 7  
  15. argv[optind - 1] = admin  
  16.   
  17. opt = d  
  18. optarg = (null)  
  19. optind = 8  
  20. argv[optind - 1] = -d  


下面来讲getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定“长参数”(或者说长选项),与getopt函数对比,getopt_long比其多了两个参数:

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

       int getopt_long(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

在这里,longopts指向的是一个由option结构体组成的数组,那个数组的每个元素,指明了一个“长参数”(即形如--name的参数)名称和性质:

           struct option {
               const char *name;
               int         has_arg;
               int        *flag;
               int         val;
           };

       name  是参数的名称

       has_arg 指明是否带参数值,其数值可选:
              no_argument (即 0) 表明这个长参数不带参数(即不带数值,如:--name)
              required_argument (即 1) 表明这个长参数必须带参数(即必须带数值,如:--name Bob)
            optional_argument(即2)表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)

       flag   当这个指针为空的时候,函数直接将val的数值从getopt_long的返回值返回出去,当它非空时,val的值会被赋到flag指向的整型数中,而函数返回值为0

       val    用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值。

另一个参数longindex,如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <getopt.h>  
  5.   
  6. int  
  7. main(int argc, char **argv)  
  8. {  
  9.    int opt;  
  10.    int digit_optind = 0;  
  11.    int option_index = 0;  
  12.    char *optstring = "a:b:c:d";  
  13.    static struct option long_options[] = {  
  14.        {"reqarg", required_argument, NULL, 'r'},  
  15.        {"noarg",  no_argument,       NULL, 'n'},  
  16.        {"optarg", optional_argument, NULL, 'o'},  
  17.        {0, 0, 0, 0}  
  18.    };  
  19.   
  20.    while ( (opt = getopt_long(argc, argv, optstring, long_options, &option_index)) != -1)  
  21.    {  
  22.         printf("opt = %c\n", opt);  
  23.         printf("optarg = %s\n", optarg);  
  24.         printf("optind = %d\n", optind);  
  25.         printf("argv[optind - 1] = %s\n",  argv[optind - 1]);  
  26.         printf("option_index = %d\n", option_index);  
  27.    }  
  28.   
  29.    return 0;  
  30. }  

编译运行以上程序并运行,可以得到以下结果:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. cashey@ubuntu:~/Desktop/getopt$ ./test_getopt_long -a 100 --reqarg 100 --nonarg  
  2. opt = a  
  3. optarg = 100  
  4. optind = 3  
  5. argv[optind - 1] = 100  
  6. option_index = 0  
  7. opt = r  
  8. optarg = 100  
  9. optind = 5  
  10. argv[optind - 1] = 100  
  11. option_index = 0  
  12. ./test_getopt_long: unrecognized option '--nonarg'  
  13. opt = ?  
  14. optarg = (null)  
  15. optind = 6  
  16. argv[optind - 1] = --nonarg  
  17. option_index = 0  

当所给的参数存在问题时,opt(即函数返回值是'?'),如:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. cashey@ubuntu:~/Desktop/getopt$ ./test_getopt_long -a  
  2. ./test_getopt_long: option requires an argument -- 'a'  
  3. opt = ?  
  4. optarg = (null)  
  5. optind = 2  
  6. argv[optind - 1] = -a  
  7. option_index = 0  
  8. cashey@ubuntu:~/Desktop/getopt$ ./test_getopt_long --reqarg  
  9. ./test_getopt_long: option '--reqarg' requires an argument  
  10. opt = ?  
  11. optarg = (null)  
  12. optind = 2  
  13. argv[optind - 1] = --reqarg  

最后说说getopt_long_only函数,它与getopt_long函数使用相同的参数表,在功能上基本一致,只是getopt_long只将--name当作长参数,但getopt_long_only会将--name和-name两种选项都当作长参数来匹配。在getopt_long在遇到-name时,会拆解成-n -a -m -e到optstring中进行匹配,而getopt_long_only只在-name不能在longopts中匹配时才将其拆解成-n -a -m -e这样的参数到optstring中进行匹配。



FROM:  http://blog.csdn.net/cashey1991/article/details/7942809

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

getopt和getopt_long函数 的相关文章

  • 在ubuntu下如何搜索文件?

    1 whereis 文件名 特点 快速 但是是模糊查找 例如 找 whereis mysql 它会把mysql mysql ini mysql 所在的目录都找出来 我一般的查找都用这条命令 2 find name 文件名 特点 准确 但速度
  • 磁盘性能指标—IOPS、吞吐量及测试

    磁盘性能指标 IOPS 吞吐量及测试 IOPS 吞吐量 磁盘服务时间 最大IOPS的理论计算方法 IOPS Input Output Per Second 即每秒的输入输出量 或读写次数 是衡量磁盘性能的主要指标之一 IOPS是指单位时间内
  • shell内置命令集合

    1 help 显示所有内置命令的列表 或某一个内置命令的用法 help 查看所有内置命令 help 内置命令 查看内置命令使用方法 help s 内置命令 显示内置命令的语法格式 非常好用哦 root localhost var help
  • eclipse的Toggle Block Selection Mode功能---列模式

    快捷键 Alf Shift A Toggle Block Selection Mode 块选择模式开关 用法 首先用快捷键或者toolbar打开选择模式 会出现一个十字 表明块选择模式已开启 选中要统一修改的块 可以从 剪贴板ctrl v替
  • linux 硬盘分区,分区,删除分区,格式化,挂载,卸载笔记

    linux 虽然一直都有在玩 但是对硬盘操作确实不是很熟悉今天有空 就整理了下 1 创建分区 先查看下是否有磁盘没有分区 html view plain copy fdisk l 其中第一个框和第二个框 是已经分好区的磁盘 第三个硬盘没有分
  • shell的内置命令

    shell有很多内置在其源代码中的命令 这些命令是内置的 所以shell不必到磁盘上搜索它们 执行速度因此加快 bash提供的help功能 能提供任何内置命令的在线帮助 表14 12列出了这些内置命令 表14 12 内置命令 命 令 功 能
  • linux下出现ping:unknown host www.baidu.com问题时的解决办法——ubuntu下局域网络的配置

    如果ping域名的时候出现ping unknown host xxx xxx 但是ping IP地址的时候可以通的话 可知是dns服务器没有配置好 查看一下配置文件 etc resolv conf 里面是否有nameserver xxx x
  • getopt和getopt_long函数

    平时在写程序时常常需要对命令行参数进行处理 当命令行参数个数较多时 如果按照顺序一个一个定义参数含义很容易造成混乱 而且如果程序只按顺序处理参数的话 一些 可选参数 的功能将很难实现 在Linux中 我们可以使用getopt getopt
  • Linux查看文件和日志的常用命令

    Linux查看文件和日志的常用命令 当项目部署和运行起来后 会产生很多的运行日志 日志的内容是程序里定义的重要输出信息 还有程序出错的报错信息 查看日志文件大部分是去日志中获取一些数据 确认某些信息 还有定位问题时查看报错信息 查看文件是查
  • Linux共享内存的查看和删除

    使用的总结 1 共享内存查看 命令 ipcs m Shared Memory Segments key shmid owner perms bytes nattch status 0x00000000 1867776 root 600 39
  • Ubuntu上安装 Emacs 24的几种方法

    1 首选当然是在Ubuntu Software Center 中找或者 apt get install emacs 可惜的是只有emacs23版本的 所以此路不通 放弃 现在Ubuntu12 04开始已经有了Emacs24 不过还是不推荐
  • linux中解压tar.gz或zip类型的文件到具体文件夹

    zip对应的解压缩命令为unzip 命令格式 unzip 选项 压缩包名 选项 d 指定解压缩位置 示例 unzip d tmp test zip 将tar gz文件解压到指定的目录中 tar zxvf tmp tar gz C tmp 在
  • Linux Shell学习简单小结(更新中……)

    if fi bin bash 删除文件 和 新建文件 file readme function delFile if e file then rm f file echo del file fi function addFile if f
  • Unix哲学

    Unix哲学 起源于Ken Thompson在早期关于如何设计一个设计接口简洁 小巧精干的操作系统的思考 随着Unix文化在学习如何尽可能发掘Thompson设计思想的过程中不断成长 同时它还一路上博采众长 Unix哲学并不是一个正规的设计
  • shell 脚本学习之一 ------let,echo,变量

    首先看到好多以这样开头的 bin bash 这个是告诉系统 解释此脚本文件的Shell程序 这个是注释行 当行有效 脚本程序一般用 xx sh 文件表示 这样一样就可以看出文件的属性 当然也可以不这样 一个脚本程序写完后 如果要执行它 则必
  • 设置vim 永久显示行号

    在linux环境下 vim是常用的代码查看和编辑工具 在程序编译出错时 一般会提示出错的行号 但是用vim打开的代码确不显示行号 错误语句的定位非常不便 那么怎样才能让vim显示代码的行号呢 1 临时显示行号 如果只是临时显示vim的行号
  • shell提取字符串中的数字保存到变量中

    1 提取数字到变量 temp echo helloworld20180719 tr cd 0 9 echo temp 输出 20180719 2 重定向到文件 echo helloworld20180719 tr cd 0 9 gt mid
  • Shell数组:shell数组的定义、数组长度

    Shell在编程方面比Windows批处理强大很多 无论是在循环 运算 bash支持一维数组 不支持多维数组 并且没有限定数组的大小 类似与C语言 数组元素的下标由0开始编号 获取数组中的元素要利用下标 下标可以是整数或算术表达式 其值应大
  • linux centos使用rz、sz命令上传下载文件

    一般情况下 我们会使用终端软件 如 XShell SecureCRT 或 FinalShell 来连接远程服务器后 使用 rz 命令上传本地文件到远程服务器 再解压发版上线 一 安转使用 系统 Linux CentOS 7 安装 rz 和
  • linux centos使用rz、sz命令上传下载文件

    一般情况下 我们会使用终端软件 如 XShell SecureCRT 或 FinalShell 来连接远程服务器后 使用 rz 命令上传本地文件到远程服务器 再解压发版上线 一 安转使用 系统 Linux CentOS 7 安装 rz 和

随机推荐

  • Git使用连接Gitee

    第一步 下载安装git Git下载链接 https www git scm com download 安装时选择哪些选项 建议百度 或者照着视频安装 码云官网 https gitee com 第二步 建议将git配置到环境变量 直接在cmd
  • 3.5离散时间模拟

    在日常生活中 我们经常会遇到许多为了公共秩序而需要排队的情景 这样一类活动中模拟程序通常需要用到队列和线性表之类的数据结构 因此是队列的典型应用之一 例如银行业务的模拟程序 假设某银行有4个窗口对外接待客户 由于每个窗口每次只能服务一个客户
  • Git 配置:设置用户名(user.name)和 邮箱(user.eamil)

    Git 配置 设置用户名 user name 和 邮箱 user eamil 原因 Git 提交代码时 会要求提供 用户名 和 邮箱 解决方案 配置 全局 user name 和 user email 使所有的 Git 仓库都使用统一的用户
  • Python计算机视觉(二)

    Python计算机视觉 二 图像处理 图像阈值 添加噪音 高斯噪音 椒盐噪音 图像平滑处理 形态学 腐蚀操作 形态学 膨胀操作 开运算与闭运算 梯度运算 图像梯度 Sobel算子 Sobel算子 Scharr算子 laplacian算子 C
  • Eclipse三种文件目录folder,source folder,package的关系及Build Path的作用

    我们在使用Eclipse导入项目时 由于导入的只是普通的文件目录 需要特殊文件 如 classpath或 project或 xml等 帮助我们识别项目目录结构 否则我们会无法运行java程序 但是当我们导入的项目没有这些文件时 又需要我们手
  • 吃透JAVA的Stream流操作,多年实践总结

    在JAVA中 涉及到对数组 Collection等集合类中的元素进行操作的时候 通常会通过循环的方式进行逐个处理 或者使用Stream的方式进行处理 例如 现在有这么一个需求 从给定句子中返回单词长度大于5的单词列表 按长度倒序输出 最多返
  • 一般通用护网保障简单归纳

    一般通用护网保障简单归纳 1 简介 1 1 护网保障 通常每年特定时间 或特殊时期由省政府 市政府牵头承办 各机关单位配合进行的 网络安全实战攻防演练 行动时间通常由承办单位决定 通常为24小时 跨周末进行 行动评比得分排名靠前的队伍予以通
  • selenium的日期定位发送数据

    https blog csdn net huilan same article details 52385401
  • 深入浅出统计学(十一)总体和样本的估计

    基本概念 问题 章节理解 上一章主要讲解如何用样本估计总体参数 这一章主要是讲解如何用总体估计样本的概率分布
  • Java判断对象是否为空(包括null ,"")

    package com gj5u publics util import java util List 判断对象是否为空 author Rex public class EmptyUtil 判断对象为空 param obj 对象名 retu
  • 自动生成网站的工具

    对大部分同学来说 有自己的网站是很酷的事情 我还记得自己第一次亲手搭建个人博客时 真的是满满的成就感 但不得不说 随着技术的发展和开源 如今现成的东西实在太多了 想要拥有个人网站 基本也都不用自己写代码了 几分钟就能轻松搞定 下面就分享一波
  • G++ 添加头文件和库文件,生成动态库和静态库

    1 添加头文件 报错 fatal error h No such file or directory 1 1通过编译指令 I添加 例如头文件位置 home ubuntu include test h 添加方式g main cpp I hom
  • kubernetes下traefik配置http3

    traefik http3介绍 traefik 2 5的rc版本已经开始支持http3 目前版本是2 6 要实现traefik的http3功能有两个注意事项 1 启动traefik的时候要加两个配置 experimental http3 t
  • Android组件化 引用另外一个Android工程, Android studio 把project项目(非moudle)引入另一个项目作为Lib进行调用

    首先创建两个工程 A MyApplication 主工程 B MyModuleTest 被当做lib依赖的工程 为了叙述方便 在下面的用A B来代替原工程名 在B工程下进行如下修改 如果B工程下 也有lib 在这里如 myuitls mod
  • uniapp使用安卓原生插件(包含插件带第三方jar)

    前言 为了公司需要uniapp引用一个第三方的jar包实现相关功能 只好用安卓封装这个第三方jar包 然后自己将api封装实现 再暴露给uniapp使用 第一次研究安卓 若有啥不对的 或者写得不好的地方 请大家指正 努力学习 一直进步 一
  • LocalDate常用技巧

    LocalDate是Java8新增的处理日期的类 使用起来比java utils date方便了许多 记录一些常用技巧 取当前日期 LocalDate today LocalDate now gt 2014 12 24 根据年月日取日期 L
  • Java并发

    Java并发 学习资料 Java并发 知识点概述 Java并发 基础 并行和并发 并行是指 并排行走 或 同时实行或实施 在操作系统中是指 一组程序按独立异步的速度执行 无论从微观还是宏观 程序都是一起执行的 对比地 并发是指 在同一个时间
  • c语言实现单链表的创建(完整版)

    使用c语言实现单链表是考研的重点 但是如何实现却是一个难点 下面是我写的一个简单的创建单链表的代码 include
  • 招投标信息爬虫 (只上最简单的版本,仅用于技术交流)

    import requests url http manager zjzfcg gov cn cms api cors getRemoteResults noticeId 6000337 url http 3A 2F 2Fnotice zc
  • getopt和getopt_long函数

    平时在写程序时常常需要对命令行参数进行处理 当命令行参数个数较多时 如果按照顺序一个一个定义参数含义很容易造成混乱 而且如果程序只按顺序处理参数的话 一些 可选参数 的功能将很难实现 在Linux中 我们可以使用getopt getopt