Linux下参数处理函数--getopt函数族

C/C++命令行参数解析:getopt函数族原理与实战指南 命令行参数解析是程序与用户交互的基础技术,其核心在于将用户输入的字符串序列转化为程序内部可处理的结构化数据。传统手动解析argv数组的方式不仅代码冗余,且难以处理短选项、长选项、带参选项等复杂组合,易引入错误。getopt函数族作为POSIX标准的一部分,通过定义选项字符串和结构体数组,实现了参数解析的标准化与自动化,显著提升代码健壮性和可维护性。在C/C++开发中,尤其在构建需要复杂配置的命令行工具(如涉及ncurses库的项目)时,掌握getopt及其增强版getopt_long至关重要。本文以工程实践 阅读详情

Linux下开发C程序,甚至是GUI程序,都可能需要处理复杂的命令行参数。健全、可靠的复杂命令行参数处理机制,可使程序方便使用,也更显专业。Linux下几乎所有的命令都提供了参数处理机制,包括短选项和长选项。

  POSIX标准中对程序名、参数作了如下相关约定:
    * 程序名不宜少于2个字符且不多于9个字符;
    * 程序名应只包含小写字母和阿拉伯数字;
    * 选项名应该是单字符活单数字,且以短横‘-‘为前綴;
    * 多个不需要选项参数的选项,可以合并。(譬如:foo -a -b -c ---->foo -abc)
    * 选项与其参数之间用空白符隔开;
    * 选项参数不可选。
    * 若选项参数有多值,要将其并为一个字串传进来。譬如:myprog -u "arnold,joe,jane"。这种情况下,需要自己解决这些参数的分离问题。
    * 选项应该在操作数出现之前出现。
    * 特殊参数‘--'指明所有参数都结束了,其后任何参数都认为是操作数。
    * 选项如何排列没有什么关系,但对互相排斥的选项,如果一个选项的操作结果覆盖其他选项的操作结果时,最后一个选项起作用;如果选项重复,则顺序处理。
    * 允许操作数的顺序影响程序行为,但需要作文档说明。
    * 读写指定文件的程序应该将单个参数'-'作为有意义的标准输入或输出来对待。

  GNU鼓励程序员使用--help、--verbose等形式的长选项。这些选项不仅不与POSIX约定冲突,而且容易记忆,另外也提供了在所有GNU工具之间保持一致性的机会。GNU长选项有自己的约定:
    * 对于已经遵循POSIX约定的GNU程序,每个短选项都有一个对应的长选项。
    * 额外针对GNU的长选项不需要对应的短选项,仅仅推荐要有。
    * 长选项可以缩写成保持惟一性的最短的字串。
    * 选项参数与长选项之间或通过空白字符活通过一个'='来分隔。
    * 选项参数是可选的(只对短选项有效)。
    * 长选项允许以一个短横线为前缀。

  C程序通过argc和argv参数访问它的命令行参数,通过main()函数调用和处理:int main(int argc, char *argv[])。一般情况下,我们事先约定好参数的顺序位置,然后在main函数中进行简单处理。这种方式实现比较简单,然后用户使用起来很不方便,Linux下的各种工具的命令行参数可以是不分先后次序的。幸运的是,Linux为C程序员提供了相关的命令行参数解析函数:getopt()和getopt_long(),分别用于处理短选项和长选项,当然后者可以同时处理短、长选项。函数原型如下:

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

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


          getopt() 函数是一个标准库调用,可允许使用直接的 while/switch 语句方便地逐个处理命令行参数和检测选项(带或不带附加的参数)。getopt_long() 允许在几乎不进行额外工作的情况下处理更具描述性的长选项,非常受开发人员的欢迎。下面用笔者开发的一个Daemon程序wsiod中的参数处理来说明具体的处理过程。wsiod参数帮助信息如下:

[liuag] /home/liuag/workspace/WSIO/WSIO-1.3/server > ./wsiod --help
Usage:  wsiod [OPTION]

WSIO server based on web service.
Mandatory arguments to long options are mandatory for short options too.
        -h, --host           hostname in soap_bind, default is host which the service runs
        -p, --port           port which the sercer runs on, default is 8080
        -b, --backlog        request backlog, default is 100
        -t, --type           server type, default is COMMON
        -k, --keepalive      attempt to keep socket connections alive
        -c, --chunk          use HTTP chunking
        -d, --dime           use DIME encoding
        -D, --debug          print debug info
            --help           print this help

Server type:
        COMMON               the simplest server
        STANDALONE           stand-alone server, which can run on port 80
        MULTITHREAD          multi-thread stand-alone server
        POOL                 using a pool of servers
        QUEUE                using a queue of requests for server
        GSI                  prethreaded server with GSI enabled

Report bugs to <Aigui.LIU@ihep.ac.cn>.

wsiod参数处理实现C程序段如下:

#include <unistd.h>
#include <getopt.h>

enum SERVERTYPE{COMMON, STANDALONE, MULTITHREAD, POOL, QUEUE, GSI};
int keepalive = 0, dime = 0, chunk = 0;

/* WSIO server main function */
int main(int argc, char **argv)
{
  int c;
  char host[128] = "localhost";
  char log_buf[LOGBUFSZ];
  int port = 8080, backlog = 100;
  enum SERVERTYPE servertype  = COMMON;
  int helpflg = 0,
      errflg = 0,
      debug = 0;
  struct option longopts[] =
  {
    {"host", 1, 0, 'h'},
    {"port", 1, 0, 'p'},
    {"backlog", 1, 0, 'b'},
    {"type", 1, 0, 't'},
    {"keepalive", 0, 0, 'k'},
    {"chunk", 0, 0, 'c'},
    {"dime", 0, 0, 'd'},
    {"debug", 0, 0, 'D'},
    {"help", 0, &helpflg, 1},
    {0, 0, 0, 0}
  };

  while ((c = getopt_long (argc, argv, "h:p:b:t:kcdD", longopts, NULL)) != EOF)
  {
    switch(c)
    {
      case 'h':
        sprintf(host, "%s", optarg);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'b':
        backlog = atoi(optarg);
        break;
      case 't':
        switch(*optarg)
    {
      case 'C':
        servertype = COMMON;
        break;
      case 'S':
        servertype = STANDALONE;
        break;
      case 'M':
        servertype = MULTITHREAD;
        break;
      case 'P':
        servertype = POOL;
        break;
      case 'Q':
        servertype = QUEUE;
        break;
      case 'G':
        servertype = GSI;
      default:
        break;
    }
        break;
      case 'k':
          keepalive = 1;
    break;
      case 'c':
          chunk = 1;
    break;
      case 'd':
          dime = 1;
    break;
      case 'D':
          debug = 1;
    break;
      case '?':
        errflg++;
        break;
      default:
        break;
    }
  }

  if(helpflg || errflg)
  {
     fprintf(stderr,"Usage:    wsiod [OPTION]/n/n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
         "WSIO server based on web service./n",
    "Mandatory arguments to long options are mandatory for short options too./n",
    "/t-h, --host           hostname in soap_bind, default is host which the service runs/n ",
    "/t-p, --port           port which the sercer runs on, default is 8080/n",
    "/t-b, --backlog        request backlog, default is 100/n",
    "/t-t, --type           server type, default is COMMON/n",
    "/t-k, --keepalive      attempt to keep socket connections alive/n",
        "/t-c, --chunk          use HTTP chunking/n",
        "/t-d, --dime           use DIME encoding/n",
        "/t-D, --debug          print debug info/n",
    "/t    --help           print this help/n/n",
    "Server type:/n",
    "/tCOMMON               the simplest server/n",
    "/tSTANDALONE           stand-alone server, which can run on port 80/n"
    "/tMULTITHREAD          multi-thread stand-alone server/n",
    "/tPOOL                 using a pool of servers/n",
    "/tQUEUE                using a queue of requests for server/n",
    "/tGSI                  prethreaded server with GSI enabled/n/n",
    "Report bugs to <Aigui.LIU@ihep.ac.cn>./n"
     );
    exit(0);
  }

  /* 省略部分 */

  return 0;
}


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/liuben/archive/2008/04/05/2252929.aspx

Ubuntu 18.04 手动编译 Radamsa 实战指南:解决 apt 版本过旧与协议模糊测试失效问题 Radamsa 是一款基于语法变异的协议模糊测试工具,其核心原理并非随机字节扰动,而是对输入模板(如 HTTP 请求、TLS 握手包)进行结构感知的确定性变异,依赖预定义的 17 类变异规则和 RFC 合规解析逻辑。技术价值在于可复现 crash、零依赖部署与协议层精准扰动能力,广泛应用于 HTTP 服务逻辑缺陷挖掘、TLS 握手 fuzzing、文件解析器内存破坏测试及工业协议解析器崩溃验证等场景。在 Ubuntu 18.04 等老旧系统中,官方 apt 源提供的 Radamsa 0.3 版本存在严重功能 阅读详情

相关推荐

深入解析设计规则检查约束:set_max_transition与set_max_capacitance的实战应用

本文深入解析了芯片设计中的关键设计规则检查约束set_max_transition与set_max_capacitance。通过剖析信号转换时间与负载电容的原理,结合实战案例,阐述了如何设置约束以保障信号完整性、控制功耗与时序,并提供了在综合与布局布线阶段的应用策略与修复方法。

weixin_29233857的博客 173

Linux C/C++ 处理命令行参数

到目前为止,大部分人编写的所有程序都可以用一个命令运行。举个例子,如果我们编译了一个称之为myprog./myprog但是,如果你想从命令行向正在运行的程序传递信息,该怎么办?考虑一个更复杂的程序,比如 GCC。要编译myprog字符串-o,myprog和myprog.c都是 gcc 的命令行参数。(从技术上讲,gcc也是一个参数,我们稍后会看到)命令行参数非常有用。毕竟,如果不能向 C 函数传递参数,C 函数就不会很有用了——添加向程序传递参数的功能会使它们更有用。

bluebird_shao的专栏 4372

【GNSS测试技术(一)】GNSS基础原理介绍

GNSS(全球卫星导航系统)是一种基于卫星信号的定位技术,通过使用分布在地球轨道上的卫星,为用户提供全球范围内的定位、导航和授时服务。

新猿异码的博客 5751

Linux下的命令行参数和环境变量

所以说我们自己的可执行程序要带上路径才能执行就是因为我们的程序不在PATH环境变量下的路径当中。其实linux下的指令是有默认搜索路径的,也就是当你使用该指令时,linux会自动在默认路径里面去找而该默认路径是什么呢?其实这是一个全局的二级字符指针,指向的正是环境变量表中的内容(也就是指向char*[]的类型)所以无论哪里我们都可以通过该指针去访问环境变量列表里的内容。用于指定可执行程序的搜索路径,当输入一个不带路径的命令时,系统会默认在PATH的内容中按照顺序在路径列表中查找可执行程序的所在路径。

C_Rio的博客 3229

手把手教你用Simulink搭建PMSM FOC控制模型(附完整仿真文件下载)

本文手把手教你使用Simulink搭建完整的永磁同步电机(PMSM)磁场定向控制(FOC)仿真模型。内容涵盖从电机与逆变器建模、核心的坐标变换(Clark/Park变换)实现、电流环与速度环PID整定,到SVPWM调制与系统集成调试的全过程,并提供关键参数设置与实用调试技巧,帮助工程师快速掌握FOC的工程实现。

silver的专栏 862

西电 程序设计基础课程设计 作业

当时做的程序设计课程的作业. 一共五题, 以报告的形式提交. 质量应该比较高(高傲). 完整内容在这里 高精度计算 问题描述 涉及知识点: 数组, 流程控制, 函数等 要求: 用整型数组表示10进制大整数(超过 2322^{32}232 的整数), 数组的每个元素存储大整数的一位数字, 实现大整数的加减法. 问题分析 结构设计 可将高精度整数写成一个类. 成员变量有: int a[MAXN], len; bool negative; 其中, 数组a用来存储大整数的一个数位, a[1]为个位上的数字, a

Wings 2513

Linux常用命令及其参数释义

Linux常用命令

欢迎。 1445

国内开发者福音:手把手教你用微软Authenticator搞定GitHub 2FA验证(附Recovery Codes保存指南)

本文详细介绍了国内开发者如何使用微软Authenticator中国版轻松配置GitHub双重身份验证(2FA),解决短信验证不可用和国际验证器访问困难的问题。重点强调了恢复码(Recovery Codes)的安全备份策略,确保账户安全无忧。

weixin_28840143的博客 435

Linux C语言 28-命令行参数

C语言 命令行参数、argc、argv,相关C库函数:printf

Tianwx的博客 771

计算机网络之NAT的解释与实验配置

NAT 静态NAT 动态NAT easy_ip NAT服务器映射

爱学习的JackYang的博客 1916

第21章 分层架构软件测试

技术人员和客户代表对代码服务相关的技术进行详细的交流,由此确定代码审计的方案(哪些代码要审计、用什么方式审计、审计的时间、审计的要求等)代码审计报告提交和沟通之后,跟开发人员针对代码审查发现的问题进行修改,然后代码审查人员进行回归的检查,然后提交复查的报告;本层不需要了解其它层的实现细节,只需要考虑与本层相关的两层之间的接口和调用的情况。然后对客户要求的功能点进行人工的代码审查,对源代码的扫描结果进行人工的分析和确认;结合自动化扫描的结果和人工审查的结果生成测试对象的代码审查报告,最后提交给客户;

李黏黏的博客 3270

linux -c 参数详解,linux c __attribute__详解

1.Declaring Attributes of Functions我这里只列举常用,或者说是我认为常用,有用的1.1 alias ("target"):函数别名The alias attribute causes the declaration to be emitted as an alias for another symbol, which must be specified. For ...

weixin_39575054的博客 391

IM 系统设计:仿微信架构,Netty + Protobuf + WebSocket 如何支撑百万级长连接?

相比 JSON,Protobuf 的体积通常只有前者的 1/5 到 1/10,且解析速度快一个数量级。// 消息类型:1-登录,2-心跳,3-单聊,4-群聊,5-ACK// 发送方ID// 接收方ID// 消息内容// 时间戳// 消息唯一ID,用于去重和ACK。

BUG猿的博客 1378

【Linux系统编程】-进程

进程(程序)是存储在存储介质(硬盘)上的一段代码,它在运行时被加载到内存空间(RAM)中。CPU会为进程分配一块地址空间,这块地址空间是虚拟的,并且可能与其他进程共享(mmap)。操作系统会将文件的物理扇区映射到进程的虚拟地址空间,而内存管理单元(MMU)负责处理虚拟地址到物理地址的转换。进程通过操作系统提供的API(应用程序编程接口)来执行任务。进程的执行是通过CPU的寄存器来控制的。

knoci的博客 877

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Linux进程管理:fork与exec原理及实践

进程是操作系统资源分配的基本单位,Linux通过进程控制块(PCB)管理进程信息。fork()系统调用通过复制PCB创建新进程,实现父子进程并发执行,而exec族函数则用于加载新程序映像。这种fork-exec组合是Linux系统编程的核心模式,广泛应用于服务器进程管理、命令行工具开发等场景。理解进程创建、通信和调度机制,能帮助开发者构建高性能、稳定的后台服务。本文以Linux进程管理为例,深入解析fork()工作原理和exec函数家族的使用技巧,并介绍进程池、管道实现等实用技术。

weixin_34234829的博客 326

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Linux系统程序设计核心:文件I/O、进程管理与信号处理详解

系统调用是操作系统为用户程序提供服务的核心接口,它实现了用户空间与内核空间的交互,是理解操作系统工作原理的基础。通过系统调用,程序可以请求内核执行文件操作、进程控制、网络通信等底层功能,从而实现对硬件资源的直接管理。掌握系统调用的原理与使用,对于开发高性能、高可靠性的系统软件至关重要,尤其在服务器开发、嵌入式系统和性能优化等场景中。本文聚焦Linux系统程序设计,深入探讨文件描述符、进程创建与通信机制,并结合fork()、exec()等热词,解析写时复制、僵尸进程等核心概念,帮助开发者从底层理解Linux程

weixin_30399155的博客 473

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

python标准库、threading、multiprocessing、aiomultiprocess、进程/线程 同步、queue(队列)

multiprocessing 包提供了本地和远程并发操作,通过使用子进程而非线程有效地绕过了全局解释器锁。 因此,multiprocessing 模块允许程序员充分利用给定机器上的多个处理器。

freeking101的博客 2万+

linux 文字模式下指令的详细说明

文字模式下指令的下達 開始下達指令, 語系的支援 重要的幾個熱鍵[Tab], [ctrl]-c, [ctrl]-d, [shift]+[UP/DOWN] Linux系統的線上求助man page與info page 指令的 --help 求助說明 man page, info page 其他有用的文件(documents)

开发仔 1984

wget:命令行下载工具

一、语法 onlylove@ubuntu:~$ wget -help GNU Wget 1.20.3, a non-interactive network retriever. Usage: wget [OPTION]... [URL]... Mandatory arguments to long options are mandatory for short options too. Startup: -V, --version display the ver

OnlyLove_的博客 1135

linux按文件名排序,linux按照文件后缀进行排序

服务器上面有很多文件,xxx.1,xxx2.1,xxxx3.1,yyy.2,yyy2.2yyy3.2,zzz.3,zzz2.3类似这样的,现在想安装文件的后缀对该文件进行排序,需要查看sort命令。命令如下:ls |sort -n -t '.' -k2即可。sort --helpUsage: sort [OPTION]... [FILE]...or: sort [OPTION]... --fil...

weixin_29663061的博客 1626

python argparse处理命令行参数

欢迎关注”生信修炼手册”!对于脚本编程而言,经常需要从命令行传递参数到脚本中。对于命令行参数的定义和使用,有一套完整的规则,以linux上的ls命令为例ls --help Usage: ...

庐州月光的博客 1124

linux-ls命令参数详解&统计目录下文件和目录的个数实例

[us11@MGHJ_YW_mg-file01 ~]$ man ls LS(1)                            User Commands                           LS(1) NAME        ls - list directory contents SYNOPSIS        ls [OPTION]... [

wuxu_nanjing的博客 879

Linux命令解释之head

用法:head [选项]… [文件]… Print the first 10 lines of each FILE to standard output. With more than one FILE, precede each with a header giving the file name. With no FILE, or when FILE is -, read standard input. Mandatory arguments to long options are mandatory

qq_43058317的博客 426

深入理解Linux操作系统-窥探运维之道

CPU相关 Top 作用:显示、管理执行中的程序 语法: Usage: top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o field -w [cols] 常用参数: d:改变显示的更新速度,或是在交谈式指令列(interactive command)按s q:没有任何延迟的显示速度,如果使用者是有superuser 的权限,则top将会以最高的优先序执行 c:切换显示模式,共有两种模式,一是只显示执行档的名称,另一种是显示完整的路径与名称

qq_45455361的博客 754

Red Hat linux 6.5 学习使用笔记《一》linux系统常用命令

Red Hat linux 6.5 学习使用笔记(linux常用命令) 1. 命令行简介 2.查看命令帮助 3.type命令 4.man的用法 5.help的用法 6.ls命令 7.cd命令 8.date命令 9.heclock命令 10.cal命令 11.echo命令 12.printf命令

kevinhanser 2728

Linux中c程序命令行参数解析

在Linux中,较为复杂的C程序命令行参数的解析通常使用getopt, getopt_long以及getopt_long_only来进行,如下所示。 #include <unistd.h> int getopt(int argc, char *const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt; #include <getopt.

j5856004的博客 1255
上一篇: B-树伪码
下一篇: Fedora桌面特效快捷键
zzulp
博客等级 码龄19年 464粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值