GETOPT函数详解

news/2025/1/24 21:19:47/

一、目的

        相信第一次接触linux的小伙伴在使用命令行时肯定有这样的疑惑,命令行各种各样的选项和选项参数是怎样实现的(各个命令的选项的含义可以通过man手册查看)。

二、介绍

        在正式介绍之前,我们先来看一下命令行选项的使用(以ls(查看目录下的内容)为例)

        1.不带选项

ls

        2.带一个选项

ls -l

        3.带多个选项

ls -a -l

        4.多个选项合并

ls -al

        另外有些选项必须带参数,有些选项参数非必须(即可以带参数也可以不带参数)

         从上面的示例可以看到选项一般以'-'开头,后面紧跟至少一个字母(建议使用a-z A-Z)(如果'-'后面存在多个字母那么选项会合并)这种形式的选项叫做短选项;如果是以"--"开头那么代表长选项(本篇不介绍),例如ls就有一个"--color=when" 选项。


        如果要实现上述类似的功能,可以用到getopt函数(只支持短选项)

        

        其中argc/argv来自int main(int argc, char **argv);

        optstring指定选项列表(举例来说optstring="abcd:e::")

        其中a代表命令行参数"-a"

                b代表命令行参数"-b"

                c代表命令行参数"-c"

                d代表命令行参数"-d123"或者"-d 123",其中123就是选项参数

                e代表命令行参数"-e123"或者"-e",注意此处的123是选项参数,‘e’和"123"之间不能有空格

        optind记录下一个命令行参数,默认值为1,也就是从argv[1]开始解析

        optopt记录当前解析的选项

        optarg记录当前选项的参数,如果未指定参数则为NULL;例如"-e123"选项optarg="123","-e"选项optarg=NULL

        opterr默认为1,当输入不识别的选项或者需要选项参数的选项没有选项参数时会报错

        getopt的返回值可以是指定的optstring里面的字符,也可能是-1;也可以是'?'和':';具体请看下面的说明。


        使用示例

#include <stdio.h>
#include <unistd.h>int main(int argc, char **argv)
{int opt;//opterr = 0; //(1)while ((opt = getopt(argc, argv, "abcd:e::-")) != -1) {printf("current char: (opt)%c-(optopt)%c, optind: %d\n", opt, optopt, optind);switch (opt) {case 'a':break;case 'b':break;case 'c':break;case 'd':printf("arguments: %s\n", optarg);break;case 'e':printf("arguments: %s\n", optarg ? optarg : "none");break;case ':':case '?':default:printf("invalid parameter\n");break;}}printf("===extra arguments===\n");while (optind < argc) {printf("%s\n", argv[optind++]);}printf("=====================\n");return 0;
}

        编译

gcc getopt_test.c -o getopt_test

        测试

         因为选项d需要指定选项参数,如果没有指定选项参数,那么getopt默认会打印错误信息,告知错误原因,并且getopt返回值为'?'

./getopt_test -d./getopt_test: option requires an argument -- d
current char: (opt)?-(optopt)d, optind: 3
invalid parameter
===extra arguments===
=====================
./getopt_test -x./getopt_test: illegal option -- x
current char: (opt)?-(optopt)x, optind: 2
invalid parameter
===extra arguments===
=====================

        如果不需要有这样的错误输出可以设置opterr=0,请查看代码注释(1)

        如果我们设置了otperr=0,那么怎么区分是指定了不支持的参数,还是选项参数未指定呢?

        有两种方法:

        第一种,通过判断optopt的值,如果optopt的值不是optstring里面的字符,就代表是非有效选项字符;

        第二种,在optstring的开头添加':',举例设置optstring为":abcd:e::",这个时候通过getopt返回值是'?'(选项不存在)还是':'(选项未指定参数)来区分 。

        


        在实际使用时,我们的命令行不仅仅有选项和选项参数,还有一些额外的参数

./getopt_test -a -b -c x y zcurrent char: (opt)a-(optopt)a, optind: 2
current char: (opt)b-(optopt)b, optind: 3
current char: (opt)c-(optopt)c, optind: 4
===extra arguments===
x
y
z
=====================

        上面的x/y/z就是命令行额外参数(位置参数)

        如果某个位置参数是'-a'时,我们应该怎么处理呢?(-a会被认为是选项a)

./getopt_test -a -b -c -- -acurrent char: (opt)a-(optopt)a, optind: 2
current char: (opt)b-(optopt)b, optind: 3
current char: (opt)c-(optopt)c, optind: 4
===extra arguments===
-a
=====================

        通过"--"我们可以将位置参数和选项隔离;

        


        选项参数是可以以‘-’开头的(不建议)

./getopt_test -d -abccurrent char: (opt)d-(optopt)d, optind: 3
arguments: -abc
===extra arguments===
=====================
./getopt_test -d-abccurrent char: (opt)d-(optopt)d, optind: 2
arguments: -abc
===extra arguments===
=====================

        "-abc"会被认为是"-d"的选项而不是选项"-a -b -c" 

以上,就是getopt函数的基本内容。


http://www.ppmy.cn/news/67144.html

相关文章

C# + .Net6 实现TensorFlow图片分类

微软官网上发现一篇很有意思的文档&#xff1a;教程&#xff1a;用于对图像进行分类的 ML.NET 分类模型 - ML.NET | Microsoft Learn 这篇教程写的很学院派&#xff0c;但有点碎&#xff0c;属于上课不能打一秒钟瞌睡的那种。好在还是给出了完整的代码&#xff1a;samples/Pro…

一文了解Moonbeam智能合约

智能合约&#xff1a;区块链交易的基石 20世纪90年代&#xff0c;Nick Szabo首次提出智能合约的概念&#xff0c;这是一个建立在自动化、加密安全世界之上的数字化市场。在这种数字化市场中&#xff0c;交易和业务可以在无需信任的情况下进行&#xff0c;无需中间人。 以太坊…

JavaScript中的数据可视化和动画效果

摘要&#xff1a; JavaScript是一种强大而灵活的编程语言&#xff0c;被广泛用于网页开发和交互设计。在数据可视化和动画效果方面&#xff0c;JavaScript提供了丰富的工具和库&#xff0c;使开发者能够创建出令人印象深刻的交互式数据可视化和动画效果。本文将介绍JavaScript中…

union和位域的混合使用

1、union&#xff08;共用体&#xff09; 1.1、概述 C 语言中&#xff0c;union是一种数据类型&#xff0c;对比于结构体&#xff0c;结构体中的每个成员都占用独立的内存空间&#xff0c;而联合中所有的成员都共享同一个内存空间。 也就是说&#xff0c;union中的不同成员要…

2023年Pycharm安装教程,附详细图解

简介 PyCharm是一款Python IDE&#xff0c;其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如&#xff0c; 调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制等等。此外&#xff0c;该IDE提供了一些高级功能&a…

Three.js 模型体素化原理及实现

在本文中&#xff0c;我们探索了 3D 模型的体素化过程&#xff0c;重点是使用导入的 glTF 模型创建 3D 像素艺术。 本文包括一个最终演示&#xff0c;涵盖了可以使用体素化实现的各种 3D 效果。 我们将提供涵盖以下主题的分步指南&#xff1a; 确定 XYZ 坐标是否在 3D 网格内的…

OSPF综合实验(第一部分)

目录 要求 确定广播域的个数 分配网段 配置路由器IP地址-优先公网配通 配置MGRE部分 拓扑结构&#xff1a; 要求 1、R4为ISP&#xff0c;其上只能配置IP地址&#xff0c;R4与其他所有直连设备间使用公有IP 2、R3~R5/6/7为MGRE环境&#xff0c;R3为中心站点 3、整个OSPF环境I…

【Linux】指令(下)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;Linux ⭐代码仓库&#xff1a;Linux 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们的支持是我…