getopt被用来解析命令行选项参数

#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储存第一个不包含选项的命令行参数。

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

1.单个字符,表示选项,

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

例如gcc -g -o test test.c ,其中g和o表示选项,test为选项o的参数。

上面是getopt()函数的基本含义,大家懂得了这些之后,我们一个例子加深一下理解。

例如我们这样调用getopt(argc, argv, "ab:c:de::");
从上面我们可以知道,选项a,d没有参数,选项b,c有一个参数,选项e有有一个参数且必须紧跟在选项后不能以空格隔开。getopt首先扫描argv[1]到argv[argc-1],并将选项及参数依次放到argv数组的最左边,非选项参数依次放到argv的最后边。

执行程序为:
      0      1    2    3  4   5      6   7    8   9 
$ ./test file1 -a  -b -c code -d file2 -e file3
  扫描过程中,optind是下一个选项的索引, 非选项参数将跳过,同时optind增1。optind初始值为1。当扫描argv[1]时,为非选项参数,跳过,optind=2;扫描到-a选项时, 下一个将要扫描的选项是-b,则optind更改为3;扫描到-b选项时,后面有参数(会认为-c为选项b的参数),optind=5,扫描到code非选项跳过optind=6;扫描到-d选项,后面没有参数,optind=7;扫描到file2非选项跳过optind=8;扫描到-e后面本来应该有参数,optind=9但是有空格所以e的参数为空。
 
扫描结束后,getopt会将argv数组修改成下面的形式
       0     1   2   3   4    5   6        7      8      9

$ ./test  -a  -b  -c  -d  -e  file1  code  file2  file3
 
同时,optind会指向非选项的第一个参数,如上面,optind将指向file1
代码如下:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
    int aflag=0, bflag=0, cflag=0;
    int ch;
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
    while ((ch = getopt(argc, argv, "ab:c:de::")) != -1)
    {
        printf("optind: %d,argc:%d,argv[%d]:%s\n", optind,argc,optind,argv[optind]);
        switch (ch) {
        case 'a':
            printf("HAVE option: -a\n\n");
    
            break;
        case 'b':
            printf("HAVE option: -b\n");
         
            printf("The argument of -b is %s\n\n", optarg);
            break;
        case 'c':
            printf("HAVE option: -c\n");
            printf("The argument of -c is %s\n\n", optarg);

break;
    case 'd':
        printf("HAVE option: -d\n");
        break;
    case 'e':
        printf("HAVE option: -e\n");
        printf("The argument of -e is %s\n\n", optarg);
        break;

case '?':
            printf("Unknown option: %c\n",(char)optopt);
            break;
        }
    }
    printf("----------------------------\n");
    printf("optind=%d,argv[%d]=%s\n",optind,optind,argv[optind]);
}
执行结果:
shiqi@wjl-desktop:~/code$ vim getopt.c
shiqi@wjl-desktop:~/code$ gcc getopt.c -o g
shiqi@wjl-desktop:~/code$ ./g file1 -a  -b -c code -d file2 -e file3
optind:1,opterr:1
--------------------------
optind: 3,argc:10,argv[3]:-b
HAVE option: -a

optind: 5,argc:10,argv[5]:code
HAVE option: -b
The argument of -b is -c

optind: 7,argc:10,argv[7]:file2
HAVE option: -d

optind: 9,argc:10,argv[9]:file3
HAVE option: -e
The argument of -e is (null)

----------------------------
optind=6,argv[6]=file1         //while循环执行完后,optind=6

 
来自--http://blog.sina.com.cn/s/blog_64ba2b750100vz5b.html

函数getopt()及其参数optind -- (转)的更多相关文章

  1. [c language] getopt 其参数optind 及其main(int argc, char **argv) 参数解释

    getopt被用来解析命令行选项参数.#include <unistd.h> extern char *optarg; //选项的参数指针extern int optind, //下一次调 ...

  2. 【Java学习笔记】函数的可变参数

    package p2; public class ParamterDemo { public static void main(String[] args) { int sum1 = add(4,5) ...

  3. Python函数中的参数(二)

    当使用混合特定的参数匹配模型时,Python将会遵循以下有关顺序的法则: 1.在函数调用中,参数必须以这样的顺序出现:任何位置参数(Value).任何关键字参数(name = Value)和*sequ ...

  4. Python函数中的参数(一)

    函数传递参数时的简要关键点: 1.参数的传递是通过自动将对象赋值给本地变量名来实现的.函数参数在实际中只是Python赋值的一个实例.因为引用是以指针的形式实现的,所有的参数实际上都是通过指针进行传递 ...

  5. ios开发@selector的函数如何传参数/如何传递多个参数

    不同的类会有不同的传递方式,参数名也不尽相同.如果是传单个参数的就不用集合,如果是传多个参数可以用类似nsarray,nsdictionary之类的集合传递.看下面例子: 例子1: 通过NSTimer ...

  6. 给setTimeout和setIntreval函数添加回调参数

    setTimeout和setInterval是两个很常见的计时函数.在以前,他们只接收两个参数,我们无法直接向他们的回调函数中添加参数,如果需要实现添加多个参数,可以在外层多嵌一层来实现类似的功能.现 ...

  7. ***php解析JSON二维数组字符串(json_decode函数第二个参数True和False的区别)

    客户端的请求体中的数据:[{"msg_id": 1, "msg_status": "HAS_READ" }, { "msg_id& ...

  8. 空函数有参函数调用参数的注意事项Swift 1.1语言

    空函数有参函数调用参数的注意事项Swift 1.1语言 7.2.3  空函数 空函数有参函数调用参数的注意事项Swift 1.1语言空函数是函数中最简单的形式.在空函数中,函数只有一个空壳,里面是没有 ...

  9. unserialize函数中的参数是否是污染数据

    1.原理 在程序编写的时候,往往需要序列化一些运行时数据,所谓序列化就是按照一定的格式将运行时数据写入本地文件.这样做可以对数据进行本地保存,用的时候直接读文件就可以把运行时产生的数据读出.php中就 ...

随机推荐

  1. Visual C++中对运行时库的支持

    原文地址:http://blog.csdn.net/wqvbjhc/article/details/6612099 一.什么是C运行时库 1)C运行时库就是 C run-time library,是 ...

  2. ubuntu 只有客人会话登录(第一次深刻感受文件权限的威力 )

    为了测试docker的挂载权限,把宿主机的/etc/passwd文件挂载到了虚机当中,进入虚机想看下能不能直接对我宿主机上的文件进行操作,把/etc/passwd删掉了最后十行...结果宿主机上的/e ...

  3. table 标签 语法

  4. NetScaler Best Practice With VMAC In A High Availability Configuration

    NetScaler Best Practice With VMAC In A High Availability Configuration https://www.citrix.com/blogs/ ...

  5. 2016 China Final H - Great Cells

    /************************************************************************* > File Name: H.cpp > ...

  6. 【POJ2728】Desert King(分数规划)

    [POJ2728]Desert King(分数规划) 题面 vjudge 翻译: 有\(n\)个点,每个点有一个坐标和高度 两点之间的费用是高度之差的绝对值 两点之间的距离就是欧几里得距离 求一棵生成 ...

  7. BZOJ2298:[HAOI2011]problem a——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2298 https://www.luogu.org/problemnew/show/P2519 一次 ...

  8. BZOJ2038:[2009国家集训队]小Z的袜子——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找 ...

  9. BZOJ1876:[SDOI2009]SuperGCD——C++高精度良心题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1876 Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数 ...

  10. jquery实现拖拽进度条并显示百分比

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...