#include <unistd.h>
       extern char *optarg;  //选项的参数指针
       extern int optind,   //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 
       extern int opterr,  //当opterr=0时,getopt不向stderr输出错误信息。
       extern int optopt;  //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?’、
       int getopt(int argc, char * const argv[], const char *optstring);
 调用一次,返回一个选项。 在命令行选项参数再也检查不到optstring中包含的选项时,返回-1,同时optind储存第一个不包含选项的命令行参数。

首先说一下什么是选项,什么是参数。

字符串optstring可以下列元素,
1.单个字符,表示选项,
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
3 单个字符后跟两个冒号,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。

getopt处理以'-’开头的命令行参数,如optstring="ab:c::d::",命令行为getopt.exe -a -b host -ckeke -d haha 
在这个命令行参数中,-a和-h就是选项元素,去掉'-',a,b,c就是选项。host是b的参数,keke是c的参数。但haha并不是d的参数,因为它们中间有空格隔开。

还要注意的是默认情况下getopt会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。
如getopt.exe -a ima -b host -ckeke -d haha, 都最后命令行参数的顺序是: -a -b host -ckeke -d ima haha
如果optstring中的字符串以'+'加号开头或者环境变量POSIXLY_CORRE被设置。那么一遇到不包含选项的命令行参数,getopt就会停止,返回-1。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int result;

opterr = 0;  //使getopt不行stderr输出错误信息

while( (result = getopt(argc, argv, "ab:c::")) != -1 )
    {
           switch(result)
          {
               case 'a':
                   printf("option=a, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case 'b':
                   printf("option=b, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case 'c':
                   printf("option=c, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case '?':
                    printf("result=?, optopt=%c, optarg=%s\n", optopt, optarg);
                    break;
              default:
                   printf("default, result=%c\n",result);
                   break;
           }
        printf("argv[%d]=%s\n", optind, argv[optind]);
    }
    printf("result=-1, optind=%d\n", optind);   //看看最后optind的位置

for(result = optind; result < argc; result++)
         printf("-----argv[%d]=%s\n", result, argv[result]);

//看看最后的命令行参数,看顺序是否改变了哈。
    for(result = 1; result < argc; result++)
          printf("\nat the end-----argv[%d]=%s\n", result, argv[result]);
    return 0;
}

unistd里有个 optind 变量,每次getopt后,这个索引指向argv里当前分析的字符串的下一个索引,因此
argv[optind]就能得到下个字符串,通过判断是否以 '-'开头就可。下面是个测试程序
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
    int tmp = 4;
    
    while( (tmp = getopt(argc, argv, "abck")) != -1  )
    {
           
           printf("-%c\t", tmp);
           int opt = optind ;
           while( opt < argc )
           {
                  if ( argv[opt][0] != '-' )
                  {
                       printf("%s\t", argv[opt]);
                       opt ++;
                  }
                  else
                      break;
           }
           printf("\n");
    }
    getchar();
}

函数说明  getopt()用来分析命令行参数。参数argc和argv是由main()传递的参数个数和内容。参数optstring 则代表欲处理的选项字符串。此函数会返回在argv 中下一个的选项字母,此字母会对应参数optstring 中的字母。如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。如果getopt()找不到符合的参数则会印出错信息,并将全域变量optopt设为“?”字符,如果不希望getopt()印出错信息,则只要将全域变量opterr设为0即可。

返回值  如果找到符合的参数则返回此参数字母,如果参数不包含在参数optstring 的选项字母则返回“?”字符,分析结束则返回-1。

范例  #include<stdio.h>
#include<unistd.h>
int main(int argc,char **argv)
{
int ch;
opterr = 0;
while((ch = getopt(argc,argv,”a:bcde”))!= -1)
switch(ch)
{
case ‘a’:
printf(“option a:’%s’\n”,optarg);
break;
case ‘b’:
printf(“option b :b\n”);
break;
default:
printf(“other option :%c\n”,ch);
}
printf(“optopt +%c\n”,optopt);
}

执行  $./getopt –b
option b:b
$./getopt –c
other option:c
$./getopt –a
other option :?
$./getopt –a12345
option a:’12345’

getopt 函数

函数定义:
#include 
int getopt(int argc, char * const argv[], 
        const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;

#define _GNU_SOURCE
#include

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

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

getopt()函数是用来解析命令行参数的。这里,主要解释getopt_long()。

getopt_long()的头两参数,argc和argv分别是传递给main()的参数的个数和参数数组(和main()的argc和argv是一个概念)。

getopt_long()中,optstring是一个字符串,表示可以接受的参数。例如,"a:b:cd",表示可以接受的参数是a,b,c,d,其中,a和b参数后面

跟有更多的参数值。(例如:-a host --b name)

getopt_long()中,参数longopts,其实是一个结构的实例:
struct option {
  const char *name;
    //name表示的是长参数名
  int has_arg;
    //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值
    //   required_argument(或者是1),表示该参数后面一定要跟个参数值
    //   optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
  int *flag;
    //用来决定,getopt_long()的返回值到底是什么。如果flag是null,则函数会返回与该项option匹配的val值
  int val;
    //和flag联合决定返回值
}

给个例子:

struct option long_options[] = {
  {"a123",       required_argument,      0, 'a'},
  {"c123",       no_argument,            0, 'c'},
}

现在,如果命令行的参数是-a 123,那么调用getopt_long()将返回字符'a',并且将字符串123由optarg返回(注意注意!字符串123由optarg带

回!optarg不需要定义,在getopt.h中已经有定义)
那么,如果命令行参数是-c,那么调用getopt_long()将返回字符'c',而此时,optarg是null。

最后,当getopt_long()将命令行所有参数全部解析完成后,返回-1。

看来,我说的有点混乱,那么,看个例子,我相信,代码最能说明问题:

#include 
#include 
#include 
#include

int main( int argc, char **argv )
{

struct option long_options[] = {
   {"a123",       required_argument,      0, 'a'},
   {"c123",       no_argument,            0, 'c'},
 }
 int opt;
 
 printf("starting... ");
 
 while((opt = getopt_long(argc, argv, "a:c", long_options, NULL)) != -1)
 {
  switch (opt)
  {
  case 'a':
    printf("It's a! ");
    printf("string of a:%s ",optarg);
  break;
    
  case 'c':
    printf("It's c! ");
  break;
    
  default:
    printf("You should look for help! ");
    exit(1);
  break;            
  }
 }
 printf("end... ");
 return 0;
}

编译后,假设生成a.out,可以试验一下。
./a.out -a hello -c
输出:
starting...
It's a!
string of a:hello
It's c!
end...

9、getopt的用法,被用来解析命令行选项参数的更多相关文章

  1. python argparse模块解析命令行选项简单使用

    argparse模块的解析命令行选项简单使用 util.py #!/usr/bin/env python # coding=utf-8 import argparse parser = argpars ...

  2. 命令行选项解析函数(C语言):getopt()和getopt_long()

    命令行选项解析函数(C语言):getopt()和getopt_long() 上午在看源码项目webbench时,刚开始就被一个似乎挺陌生函数getopt_long()给卡住了,说实话这函数没怎么见过, ...

  3. 命令行选项解析函数getopt()

    1.定义: int getopt(int argc, char * const argv[], const char *optstring); 2.描述: getopt是用来解析命令行选项参数的,但是 ...

  4. getopt:命令行选项、参数处理

    在写shell脚本时经常会用到命令行选项.参数处理方式,如: ./test.sh -f config.conf -v --prefix=/home -f 为短选项,它需要一个参数,即config.co ...

  5. argparse - 命令行选项与参数解析(转)

    argparse - 命令行选项与参数解析(译)Mar 30, 2013 原文:argparse – Command line option and argument parsing 译者:young ...

  6. argparse - 命令行选项与参数解析

    argparse模块作为optparse的一个替代被添加到Python2.7.argparse的实现支持一些不易于添加到optparse以及要求向后不兼容API变化的特性,因此以一个新模块添加到标准库 ...

  7. 使用getopt命令解析shell脚本的命令行选项 【转】

    本文转载自:http://yejinxin.github.io/parse-shell-options-with-getopt-command 在之前的一篇文章中,介绍了如何利用shell内置的get ...

  8. Python命令行选项參数解析策略

    概述 在Python的项目开发过程中,我们有时须要为程序提供一些能够通过命令行进行调用的接口.只是,并非直接使用 command + 当前文件 就ok的,我们须要对其设置可选的各种各样的操作类型.所以 ...

  9. python argparse模块:命令行选项及参数解析

    位置参数:给一个例子: import argparse parser = argparse.ArgumentParser() parser.add_argument("echo") ...

随机推荐

  1. Kinect 开发 —— Kinect for windows SDK

    开发 —— 基本的SDK和Windows 编程技巧(彩色图像视频流,深度图像视频流的采集,骨骼跟踪,音频处理,语音识别API) 深度数据,就是Kinect的精髓和灵魂,很多问题都转换为深度图像的模式识 ...

  2. spring webSocket The HTTP response from the server [200] did not permit the HTTP upgrade to WebSocket

    在springboot 1.5.9版本 WebSocketConfig配置 registry.addEndpoint("/webSocket").withSockJS();在加了. ...

  3. C/C++(数据结构链表的实现)

    链表 List 链表实现了内存零碎片的有效组织. 静态链表 链表中有两个成员,数据域和指针域 数据域:我们存储的数据. 指针域:指针指向下一个具体的节点,代表了下一个节点的类型是链表类型. 所谓的指针 ...

  4. tortoisegit--无法commit

    tortoisegit--无法提交,好几次使用tortoisegit,commit的时候出现卡死的情况,导致无法提交代码. 分析错误以为是: 电脑的性功能有关,但重启好几次电脑一人无济于事,打开任务管 ...

  5. 【Django】MEDIA的配置及用法

    如果需要在数据库中存储图片或视频类的数据,我们可以配置MEDIA. 下面的示例将以上传一张图片的形式来说明MEDIA的配置及用法. 第一步 settings.py # media配置 MEDIA_UR ...

  6. 【Android个人理解(八)】跨应用调用不同组件的方法

    如果情景: 创建两个应用appA和appB,appA包括一个Service,此Service有一个堵塞方法每隔10秒钟产生一个随机数字,例如以下: public int getRandomInt(){ ...

  7. BZOJ3262: 陌上花开(三维偏序,CDQ分治)

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...

  8. Vue+TypeScript学习

    Vue CLI 内置了 TypeScript 工具支持.在 Vue 的下一个大版本 (3.x) 中也计划了相当多的 TypeScript 支持改进,包括内置的基于 class 的组件 API 和 TS ...

  9. VBS 脚本调用

    https://my.oschina.net/Tsybius2014/blog/602641

  10. Spring.net的Demo项目,了解什么是控制反转

    Spring这个思想,已经推出很多年了. 刚开始的时候,首先是在Java里面提出,后来也推出了.net的版本. Spring里面最主要的就是控制反转(IOC)和依赖注入(DI)这两个概念. 网上很多教 ...