本文首发于 2014-01-10 19:48:48

1. getopt

该函数用来解析命令行参数。

1.1. 函数定义

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

前两个参数设为main函数的两个参数。

optstring设为由该命令要处理的各个选项组成的字符串。选项后面带有冒号’:’时,该选项是一个带参数的选项。

举例:make -f filename -n
-f 是一个带参数的选项,-n 是一个没有参数的选项。

可以像下面这样调用 函数getopt 来解析上面的例子。

c = getopt(argc, argv, "f:n");

此函数的返回值即为当前找到的命令选项,全部选项都找到时的返回值为-1

通常一个命令有多个选项,为了取得所有选项,需要循环调用此函数,直到返回值为-1。
要使用此函数,还有几个全局变量必须要了解:

extern char *optarg;extern int optind, opterr, optopt; /*optarg: 当前选项带参数时,optarg指向该参数。optind: argv的索引。通常选项参数取得完毕时,通过此变量可以取得非选项参数(argv[optind])optopt: 一个选项在argv中有,但在optstring中不存在时,或者一个带参数的选项没有参数时,        getopt()返回'?',同时将optopt设为该选项。opterr: 将此变量设置为0,可以抑制getopt()输出错误信息。*/

1.2. 实例

#include #include #include int main(int argc, char *argv[ ]){    int c;    int flg = 0;    char filename[256];    char testdata[256];    if (argc < 2)    {        printf("usage:%s [-f filename] [-n] testdata\n", argv[0]);        return -1;    }    opterr = 0;    while ((c = getopt(argc, argv, "f:n")) != -1)    {        switch (c)        {            case 'f':                strncpy(filename, optarg, sizeof(filename)-1);                break;            case 'n':                flg = 1;                break;            case '?':            default:                printf("usage:%s [-f filename] [-n] testdata\n", argv[0]);                return -1;        }    }    if (argv[optind] == NULL)    {        printf("usage:%s [-f filename] [-n] testdata\n", argv[0]);        return -1;    }    else    {        strncpy(testdata, argv[optind], sizeof(testdata)-1);    }    printf("fliename:%s flg:%d testdata:%s\n", filename, flg, testdata);    return 0;}

2. getopt_long

这是支持长命令选项的函数,长选项以’–’开头。

2.1. 函数定义

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

前三个参数与函数getopt的参数是一样的。
只支持长选项时,参数optstring设置为NULL或者空字符串””。
第四个参数是一个构造体struct option的数组。此构造体定义在头文件getopt.h中。此数组的最后一个须将成员都置为0。

struct option {const char *name;int has_arg;int *flag;int val;};

构造体各个成员的解释如下:

name : 长选项的名字。
has_arg : no_argument或0表示此选项不带参数,required_argument或1表示此选项带参数,optional_argument或2表示是一个可选选项。
flag : 设置为NULL时,getopt_long()返回val,设置为NULL以外时,>getopt_long()返回0,且将flag设为val。
val : 返回值或者
flag的设定值。有些命令既支持长选项也支持短选项,可以通过设定此值为短选项实现。

第五个参数是一个输出参数,函数getopt_long()返回时,longindex的值是struct option数组的索引。

关于返回值有以下几种情况:

识别为短选项时,返回值为该短选项。
识别为长选项时,如果flag是NULL的情况下,返回val,如果flag非NULL的情况下,返回0。
所有选项解析结束时返回-1。
存在不能识别的选项或者带参数选项的参数不存在时返回’?’ 。

2.2. 实例

#include      /* for printf */#include     /* for exit */#include int main(int argc, char **argv){   int c;   int digit_optind = 0;   int flag = 0;   while (1) {       int this_option_optind = optind ? optind : 1;       int option_index = 0;       static struct option long_options[] = {           {"add",     required_argument, 0,  0 },           {"append",  no_argument,       0,  0 },           {"delete",  required_argument, 0,  0 },           {"verbose", no_argument,       0,  0 },           {"create",  required_argument, 0, 'c'},           {"file",    required_argument, 0, 'f'},           {0,         0,                 0,  0 }       };       c = getopt_long_only(argc, argv, "abc:d:f:012", long_options, &option_index);       if (c == -1)           break;       switch (c) {       case 0:           printf("option %s", long_options[option_index].name);           if (optarg)               printf(" with arg %s", optarg);           printf("\n");           break;       case '0':       case '1':       case '2':           if (digit_optind != 0 && digit_optind != this_option_optind)             printf("digits occur in two different argv-elements.\n");           digit_optind = this_option_optind;           printf("option %c\n", c);           break;       case 'a':           printf("option a\n");           break;       case 'b':           printf("option b\n");           break;       case 'c':           printf("option c with value '%s'\n", optarg);           break;       case 'd':           printf("option d with value '%s'\n", optarg);           break;        case 'f':            printf("option f with value '%s'\n", optarg);            break;       case '?':           break;       default:           printf("?? getopt returned character code 0%o ??\n", c);       }   }   if (optind < argc) {       printf("non-option ARGV-elements: ");       while (optind < argc)           printf("%s ", argv[optind++]);       printf("\n");   }   exit(EXIT_SUCCESS);}

欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。

标题网址
GitHubhttps://dbkernel.github.io
知乎https://www.zhihu.com/people/…
思否(SegmentFault)https://segmentfault.com/u/db…
掘金https://juejin.im/user/5e9d3e…
开源中国(oschina)https://my.oschina.net/dbkernel
博客园(cnblogs)https://www.cnblogs.com/dbkernel