如何使用getopt()函数解析参数

最近在写程序的过程中,把一部分时间都花费在程序对参数的处理上。今天听了学长说到getopt函数,才发现原来c里面还有一个专门解决参数处理的函数,查询了相关资料,这里简单总结一下。

使用int main( int argc, char *argv[] )(或int main( int argc, char **argv ))时,系统将把用户输入的参数通过argc和argv引入程序中,argc为参数的个数,argv是指向参数的指针数组,其中第一个参数为自身程序文件名。

这里我们使用getopt() 函数对传入的参数进行处理,getopt()位于 unistd.h 系统头文件中,函数原型可以在man中查到,大家可以使用下面指令查看getopt的man手册

man 3 getopt

getopt的函数原型如下:

#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);

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

这里引用IBM对于其的解释,原文链接在这。我对其中部分错误做了更改,

给定了命令参数的数量 (argc)、指向这些参数的数组 (argv) 和选项字符串 (optstring) 后,getopt() 将返回第一个选项,并设置一些全局变量。使用相同的参数再次调用该函数时,它将返回下一个选项,并设置相应的全局变量。如果不再有识别到的选项,将返回 -1,此任务就完成了。

getopt() 所设置的全局变量包括:

extern char *optarg;  //选项的参数指针
       extern int optind,   //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 
       extern int opterr,  //当opterr=0时,getopt不向stderr输出错误信息。
       extern int optopt;  //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回‘?‘

对于每个选项,选项字符串 (optstring) 中都包含一个对应的字符。具有参数的选项后面跟有一个 : 字符。如果一个选项后面紧跟2个冒号(::),表示该选项和参数之间不使用空格隔开;

可以重复调用 getopt(),直到其返回 -1 为止;任何剩下的命令行参数通常视为文件名或程序相应的其他内容。

我们知道,一般程序的选项分为两种:带关联值的和不带关联值的,

在解析参数的时候,我们希望的是:从一堆参数中把我们要的选项和选项关联值分别找到并存到相对应的地方供我们使用,并且把其他参数找出来供我们调用。

getopt完美实现这一点。

我们在测试的时候,定义了一个全局变量来存储参数值,

typedef struct parameter
{
    int     a;        //参数a
    int     b;        //参数b
    char    *b_pri;   //参数b的关联值
    int     c;        //参数c
    char    *c_pri;   //参数c的关联值
}par;

如果遇到了其他选项,getopt() 将显示一个错误消息,程序将在显示了使用方法消息后退出。因此optString应该为

static const char *optstring = "ab:c::?";

程序运行之前,我们先对参数初始化,设定其初始值。

    //参数初始化
    opt.a = 0;
    opt.b = 0;
    opt.b_pri = NULL;
    opt.c = 0;
    opt.c_pri = NULL;

接下来就简单的把参数使用getopt处理,最后输出最后的参数就行了,看看我们的测试程序。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4
 5 typedef struct parameter
 6 {
 7     int       a;        //参数a
 8     int       b;        //参数b
 9     char *b_pri;        //参数b的关联值
10     int       c;        //参数c
11     char *c_pri;        //参数c的关联值
12 }par;
13
14
15 int main( int argc, char **argv )
16 {
17     int i;        //循环变量
18     par opt;    //参数
19     int flag = 0;    //循环退出标志位
20
21     //参数初始化
22     opt.a = 0;
23     opt.b = 0;
24     opt.b_pri = NULL;
25     opt.c = 0;
26     opt.c_pri = NULL;
27
28     //参数检测
29     if (argc == 1)
30     {
31         printf("您没有设置选项!\n");
32         exit(0);
33
34     }
35     //输出未处理的参数
36     printf("系统传入的参数为:");
37     for ( i = 1; i < argc; i++)
38     {
39         printf("%s ",argv[i]);
40     }
41     printf("\n");
42
43     //循环处理传入参数
44     while(flag != -1)
45     {
46         //调用getopt处理参数
47         switch(getopt( argc, argv, "ab:c::?"))
48         {
49             case ‘a‘:
50                 opt.a = 1;
51                 break;
52             case ‘b‘:
53                 opt.b = 1;
54                 opt.b_pri = optarg;
55                 break;
56             case ‘c‘:
57                 opt.c = 1;
58                 opt.c_pri = optarg;
59                 break;
60             case -1:
61                 flag = -1;
62                 break;
63             default:
64                 break;
65         }
66     }
67
68     if( optind != argc)
69     {
70         printf("参数中非程序选项的有:");
71         for (i = optind; i < argc; i++)
72         {
73             printf("%s\t",argv[i]);
74         }
75         printf("\n");
76     }
77
78     //输出解析结果
79     printf("解析到程序启动后启用的选项有:");
80     if (opt.a == 1)
81         printf("a,");
82     if (opt.b == 1)
83         printf("b(参数为:%s),",opt.b_pri);
84     if (opt.c == 1)
85         printf("c(参数为:%s),",opt.c_pri);
86     printf("\n");
87
88
89     //处理后,输出全部参数与原来对比
90     printf("使用getopt后,系统参数变为为:");
91     for ( i = 1; i < argc; i++)
92     {
93         printf("%s ",argv[i]);
94     }
95     printf("\n");
96
97     return 0;
98 }

保存后,编译运行。

$ ./a.out -a -b 123 3 22 -h -c1
系统传入的参数为:-a -b 123 3 22 -h -c1
./a.out: invalid option -- ‘h‘
参数中非程序选项的有:3    22
解析到程序启动后启用的选项有:a,b(参数为:123),c(参数为:1),
使用getopt后,系统参数变为为:-a -b 123 -h -c1 3 22

其中,我们传入的参数被全部解析出来,非正常选项"-h"直接显示出来,如果大家不希望非正常参数显示出来,或者希望自己处理非正常参数,可以在设置getopt中全域变量opterr = 0,在optstring的时候不加入?,例如

opterr = 0;

static const char *optstring = "ab:c::";

那么程序在检测到未知选项会返回?,我们可以这样处理

opterr = 0;    //getopt不输出错误参数

...其他程序段...

//循环处理传入参数
while(flag != -1)
{
    //调用getopt处理参数
    switch(getopt( argc, argv, "ab:c::"))
    {
        case ‘a‘:
            opt.a = 1;
            break;
        case ‘b‘:
            opt.b = 1;
            opt.b_pri = optarg;
            break;
        case ‘c‘:
            opt.c = 1;
            opt.c_pri = optarg;
            break;
        case ‘?‘:
            printf("出现非正常选项:%c\n",optopt);
            break;
        case -1:
            flag = -1;
            break;
        default:
            break;
    }
}

程序源代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4
  5 typedef struct parameter
  6 {
  7     int       a;        //参数a
  8     int       b;        //参数b
  9     char *b_pri;    //参数b的关联值
 10     int       c;        //参数c
 11     char *c_pri;    //参数c的关联值
 12 }par;
 13
 14
 15 int main( int argc, char **argv )
 16 {
 17     int i;        //循环变量
 18     par opt;    //参数
 19     int flag = 0;    //循环退出标志位
 20
 21     //参数初始化
 22     opt.a = 0;
 23     opt.b = 0;
 24     opt.b_pri = NULL;
 25     opt.c = 0;
 26     opt.c_pri = NULL;
 27     opterr = 0;    //getopt不输出错误参数
 28
 29     //参数检测
 30     if (argc == 1)
 31     {
 32         printf("您没有设置选项!\n");
 33         exit(0);
 34
 35     }
 36     //输出未处理的参数
 37     printf("系统传入的参数为:");
 38     for ( i = 1; i < argc; i++)
 39     {
 40         printf("%s ",argv[i]);
 41     }
 42     printf("\n");
 43
 44     //循环处理传入参数
 45     while(flag != -1)
 46     {
 47         //调用getopt处理参数
 48         switch(getopt( argc, argv, "ab:c::"))
 49         {
 50             case ‘a‘:
 51                 opt.a = 1;
 52                 break;
 53             case ‘b‘:
 54                 opt.b = 1;
 55                 opt.b_pri = optarg;
 56                 break;
 57             case ‘c‘:
 58                 opt.c = 1;
 59                 opt.c_pri = optarg;
 60                 break;
 61             case ‘?‘:
 62                 printf("出现非正常选项:%c\n",optopt);
 63                 break;
 64             case -1:
 65                 flag = -1;
 66                 break;
 67             default:
 68                 break;
 69         }
 70     }
 71
 72     if( optind != argc)
 73     {
 74         printf("参数中非程序选项的有:");
 75         for (i = optind; i < argc; i++)
 76         {
 77             printf("%s\t",argv[i]);
 78         }
 79         printf("\n");
 80     }
 81
 82     //输出解析结果
 83     printf("解析到程序启动后启用的选项有:");
 84     if (opt.a == 1)
 85         printf("a,");
 86     if (opt.b == 1)
 87         printf("b(参数为:%s),",opt.b_pri);
 88     if (opt.c == 1)
 89         printf("c(参数为:%s),",opt.c_pri);
 90     printf("\n");
 91
 92
 93     //处理后,输出全部参数与原来对比
 94     printf("使用getopt后,系统参数变为为:");
 95     for ( i = 1; i < argc; i++)
 96     {
 97         printf("%s ",argv[i]);
 98     }
 99     printf("\n");
100
101     return 0;
102 }

这样的话,上面同样的参数下,运行结果如下:

$ ./a.out -a -b 123 3 22 -h -c1
系统传入的参数为:-a -b 123 3 22 -h -c1
出现非正常选项:h
参数中非程序选项的有:3    22
解析到程序启动后启用的选项有:a,b(参数为:123),c(参数为:1),
使用getopt后,系统参数变为为:-a -b 123 -h -c1 3 22 

ok了,其实还有一个比getopt更好的一个选择,就是getopt_long,它可以支持长选项,因为这篇博文呢针对getopt的,所以我就不多做介绍,大家可以查man手册,或者等待我不知道什么时候的下次更新吧。

如何使用getopt()函数解析参数

时间: 2024-08-24 09:49:04

如何使用getopt()函数解析参数的相关文章

使用getopt_long来解析参数的小函数模板

getopt_long原型 #define no_argument 0 #define required_argument 1 #define optional_argument 2 struct option { const char *name; //名称,下面实例中使用的--help,--version int has_arg; //是否有参数,可选0,1,2三个值,就是上面的那三个宏定义 int *flag; //返回值,传入的一个int指针,表示该参数的解析结果,如果是NULL,那么返

[转]函数getopt(),及其参数optind

getopt被用来解析命令行选项参数. #include <unistd.h>       extern char *optarg;  //选项的参数指针       extern int optind,   //下一次调用getopt的时,从optind存储的位置处重新开始检查选项.        extern int opterr,  //当opterr=0时,getopt不向stderr输出错误信息.       extern int optopt;  //当命令行选项字符不包括在opt

函数getopt(),及其参数optind

getopt被用来解析命令行选项参数. #include <unistd.h>       extern char *optarg;  //选项的参数指针       extern int optind,   //下一次调用getopt的时,从optind存储的位置处重新开始检查选项.        extern int opterr,  //当opterr=0时,getopt不向stderr输出错误信息.       extern int optopt;  //当命令行选项字符不包括在opt

getopt_long函数解析命令行参数

转载:http://blog.csdn.net/hcx25909/article/details/7388750 每一天你都在使用大量的命令行程序,是不是感觉那些命令行参数用起来比较方便,他们都是使用getopt来实现的. 在Linux下使用getopt写程序是一种比较cool的事情,下面来简单的介绍一下getopt的使用. === getopt使用 === 在讨论参数处理之前,我们先明确两个概念:选项.选项参数gcc -g -o test test.c我们经常使用上面的命令来编译程序,这里g和

Linux getopt/getopts解析命令行参数教程

一.说明 shell中获取参数可以直接使用$1.$2等形式来获取,但这种方式有明显的限制:每个参数的位置是固定的.比如如果在设计上$1是ip地址$2是端口,那在执行时就必须第一个参数是ip第二个参数是端口而不能反过来. shell提供了getopt和getopts来解析参数,getopt比getopts功能强一些getopts比getopt简单一些:总体而言getopt和getopts都差强人意. 二.使用getopt解析参数 getopt比getopts强一些复杂一些:能在命令行中单独使用.支

document.execCommand()函数可用参数解析

隐藏在暗处的方法-execCommand() 关键字: javascript document document.execCommand()方法可用来执行很多我们无法实现的操作. execCommand方法是执行一个对当前文档,当前选择或者给出范围的命令. document.execCommand()方法处理Html数据时常用语法格式如下: 复制内容到剪贴板 代码: document.execCommand(sCommand[,交互方式, 动态参数]) 其中:sCommand为指令参数(如下例中

getopt() 函数的简介

对于程序员来说,在linux上用的最多的就是通过命令行来运行程序,但是很多人都不是很清楚命令行的书写格式规范,所以当输入错误的时候,shell就会提示输入错误之类的信息. 我们可以自己编写命令行参数解析程序,但是其实linux已经提供了一个函数来实现相关的功能,这个函数就是getopt函数. 相关函数头文件 #include<unistd.h>函数原型及相关外部变量声明 int getopt(int argc,  char* const argv[ ],  const char* optstr

C语言-getopt函数

#include<unistd.h> int getopt(int argc,char *const argv[],const char *optstring); extern char *optarg; extern int optind,opterr,optopt; optstring为一个字符列表,每个字符代表一个单字符选项 全局变量: optarg:存数据 optind opterr:控制是否向STDERR打印错误.若值为0,则关闭打印错误信息 optopt:存储出错的option(如

C语言getopt()函数

相关函数表头文件 #include<unistd.h> 定义函数 int getopt(int argc,char * const argv[ ],const char * optstring); 函数说明 该函数的argc和argv参数通常直接从main()的参数直接传递而来.optstring是选项字母组成的字串.如果该字串里的任一字符后面有冒号,那么这个选项就要求有选项参数. 当给定getopt()命令参数的数量 (argc).指向这些参数的数组 (argv) 和选项字串 (optstr