Linux下 头文件<getopt.h> 及其函数的应用

本文内容摘抄自两篇博客:

                            https://www.cnblogs.com/qingergege/p/5914218.html

                            https://blog.csdn.net/pengrui18/article/details/8078813

 

函数一:

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

参数1、2为 main函数的输入参数,参数3 为选项字符串,函数返回值为选项字符。

 

<getopt.h 文件内部的参数:

1、 extern char* optarg ;   用于保存选项。

2、 extern int   optind,  用来记录下一个检索位置。

3、 extern int   opterr,   是否将错误的信息输出到stderr,为0时表示不输出。

4、 extern int   optopt,    表示不在选项字符串optstring中的选项。

 

先来看一条指令: gcc  helloworld.c  -o  helloworld.out;  这条指令中的-o就是命令行的选项,而后面的helloworld.out 就是选项-o选项所携带的参数。 有些选项是不带参数的,而这样不带参数的选项可以写在一起, 比如说有两个选项 -c和-d,这两个选项都不带参数,那么他们是可以写在一起的,即:-cd 。

 

关于选项字符串: 比如 “a:b:cd::e”,这就是一个选项字符串。对应到命令行就是 -a, -b, -c, -d, -e 。 冒号表示参数,一个冒号就表示这个选项后面必须带有参数。这个参数可以和选项连在一起,也可以用空格隔开,比如:-a123 和 -a 123 ,都表似乎123为-a的参数。两个冒号就表示这个选项的参数是可选的,即可以有参数也可以没有参数,但要注意有参数时参数与选项之间不能有空格。

一个例子:

/*
 ============================================================================
 Name        : test.c
 Author      : lgh
 ============================================================================
 */

#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
    int ch;
    printf("\n\n");
    printf("optind:%d, opterr:%d\n",optind,opterr);
    printf("-----------------------------------------------------------\n");

    while((ch = getopt(argc, argv, "ab:c:de::")) != -1)
    {
        switch(ch)
        {
           case 'a':
               printf("a\n\n");
               printf("the argument of -a is %s\n\n",optarg);
               break;

           case 'b':
                 printf("b\n\n");
                 printf("the argument of -b is %s\n\n",optarg);
                 break;

           case 'c':
                 printf("c\n\n");
                 printf("the argument of -c is %s\n\n",optarg);
                 break;

           case 'd':
                 printf("d\n\n");
                 break;

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

           case '?':
               printf("unknown option: %c\n",(char)optopt);
               break;
        }
        printf("下一次起始搜索位置:optind = %d\n",optind);
        printf("-----------------------------------------------------------\n");
        printf("\n\n");
    }
}

 

编译后命令执行  ./test  -b  "hello world"

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
b

the argument of -b is hello world

下一次起始搜索位置:optind = 3
-----------------------------------------------------------

 

可以看到optind 和 opterr的初始值都为1 ,opterr非零表示如果发生错误,会将错误输出到stderr上。

int main(int argc, char* argv[]);   argc表示参数的个数,argv[]表示每个参数字符串。 对于./test -b "hello world" 命令,argc就为3,argv[]分别表示./test   -b  "hello world" , 实际上真正的参数从 -b 开始,也就是argv[1] ,所以optind的初始值就是1。

当执行getopt()函数时,会依次扫描每一个命令行参数(下标1开始),第一个-b是一个选项,而且这个选项在选项字符串optstring中有,b后面有冒号表示b后面必须带有参数, “hello world”就是它的参数。所以这个命令行是符合要求的。至于执行后optind为什么是3,这是因为optind是下一次getopt()函数要从argv[3]开始搜索。当然,这个例子argv[3]已经没有了,此时getopt()函数会返回-1,结束while循环。 

 

再次输入一行命令: ./test   -b  "hello world"  -c1234

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
b

the argument of -b is hello world

下一次起始搜索位置:optind = 3
-----------------------------------------------------------


c

the argument of -c is 1234

下一次起始搜索位置:optind = 4
-----------------------------------------------------------

对于这个过程,最开始optind=1 ,找到选项-b 和他的参数“hello world” ,之后搜索起始位置跳至argv[3] 找到 -c和他的参数1234(选项和参数是连在一起的),由于-c1234是写在一起的,所以他俩一起占用argv[3] ,之后搜索起始位置跳至 argv[4] ,而argv[4]为空,这样getopt()函数就会返回-1,循环结束。

 

再次输入命令:  ./test  -z 123

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
./test: invalid option -- 'z'
unknown option: z
下一次起始搜索位置:optind = 2
-----------------------------------------------------------

其中./test: invalid option -- 'z' 就是输出到stderr的错误输出 ,如果把opterr设置为0那么就不会有这条输出。

 

再次输入命令:  ./test  -zheng 

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
./test: invalid option -- 'z'
unknown option: z
下一次起始搜索位置:optind = 1
-----------------------------------------------------------


./test: invalid option -- 'h'
unknown option: h
下一次起始搜索位置:optind = 1
-----------------------------------------------------------


e

the argument of -e is ng

下一次起始搜索位置:optind = 2
-----------------------------------------------------------

由于不带参数的选项可以写在一起,所以当getopt()函数找到-z的时候,发现在optstring中没有,这时候他就认为h也是一个选项,也就是-h 和 -z写在一起了,依次类推,直到找到-e,发现optstring中有。

 

 

函数二: getopt_long_only(int argc, char* argv[], const struct char* options, int* index)
先看个例子:
/*
 ============================================================================
 Name        : test.c
 Author      : lgh
 ============================================================================
 */

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

int main(int argc, char* argv[])
{
    const char* optstring="n:v";
    int c, deb, index;
    struct option options[]=
    {
            {"username", required_argument, NULL, 'n'},
            {"version" , no_argument,       NULL, 'v'},
            {0         , 0          ,       NULL,  0 },
    };

    while((c=getopt_long_only(argc,argv,optstring, options, &index))!=-1)
    {
        switch(c)
        {
        case 'n':
            printf("username is %s\n", optarg);
            break;
        case 'v':
            printf("version is 0.0.1\n");
            break;
        case '?':
            printf("?\n");
            break;
        default:
            printf("c is %d\n",c);
            break;
        }
    }
    return 0;
}

输入指令:

   ./test   -n  "hello world" 

输出结果:

username is hello world

输入命令:

  ./test -v 

输出结果:

version is 0.0.1

struct option options[]为结构体数组, “n:v”为选项字符,他们对应的长字符分别为前面的 username 、version ;

required_argument 表示输入指令时 选项字符后面需要带参数,no_argument则表示不用带参数。 

posted on 2018-07-14 14:59  忠诚的卫士  阅读(445)  评论(0编辑  收藏  举报

导航