Linux -- getopt参数解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rikeyone/article/details/88864327

getopt函数

#include <unistd.h>

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

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

getopt函数需要传入对应的argc和argv参数表,还需要一个optstring:比如 getopt(argc, argv, “ab:c::”);

1. 单个字符表示选项,比如示例中的a选项。可以通过传入"-a"来触发选项。
2. 字符后加:表示选项后要加一个参数,比如示例中的b选项,可以通过"-b xxx"来传入选项。
3. 字符后加::表示选项后可选择加一个参数或者不加,比如示例中的c选项,可以通过"-c"或者"-cXXX"的格式来传入选项。

除了对应的getopt函数外,头文件中还定义了全局变量optarg、optind、opterr、optopt:
optind:表示下一个要被getopt解析的argv参数index索引号
optarg:如果选项后加参数的话,此变量会存入对应的参数
opterr:当getopt发现一个无法识别的选项时会打印一条错误信息到stderr,如果调用函数设置opterr=0, 此错误信息就不再打印出来。
optopt:当getopt发现一个无法识别的选项时会把对应的选项赋值给optopt,否则optopt为空,然后返回’?’。

示例:

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

int
main(int argc, char *argv[])
{
    int f_flag, opt;
    int t_flag, nsecs;

    nsecs = 0;
    f_flag = 0;
	t_flag = 0;
	opterr = 0; /*don't print getopt error message*/

    while ((opt = getopt(argc, argv, "ft:")) != -1) {
        switch (opt) {
        case 'f':
            f_flag = 1;
            break;
        case 't':
            t_flag = 1;
            nsecs = atoi(optarg);
            break;
        default: /* '?' */
            fprintf(stderr, "Usage: %s [-t nsecs] [-f] name\n",
                    argv[0]);
            fprintf(stderr, "optopt:%c\n", optopt);
            exit(EXIT_FAILURE);
        }
    }

    printf("f_flag=%d; t_flag=%d; nsecs=%d; optind=%d\n", f_flag, t_flag, nsecs, optind);

    if (optind >= argc) {
        fprintf(stderr, "expected non-option argument\n");
        exit(EXIT_FAILURE);
    } else { /* optind < argc */
        printf("non-option arguments: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

    exit(EXIT_SUCCESS);
}

getopt_long函数

#include <getopt.h>

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选项函数之外,如果我们想要支持"–help"这种类型的长选项,可以使用这个函数,这个函数可以同时定义短选项和长选项,argc和argv依然是参数表;optstring和上文一致表示的是短选项;longopts表示长选项,传入的是一个结构体数组;longindex表示当前返回的选项对应在数组中的索引index。
对应的全局变量optarg、optind依然是可以用的。关于struct option的定义:

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

如果flag为NULL,那么getopt_long匹配到选项后会返回val;否则getopt_long匹配到选项后返回值为0,flag指向的变量会被设置为val的值。

示例:

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

int
main(int argc, char **argv)
{
    int c;
    int digit_optind = 0;
	static struct option long_options[] = {
            {"add",     required_argument, NULL,  0 },
            {"append",  no_argument,       NULL,  0 },
            {"create",  required_argument, NULL, 'c'},
            {0,         0,                 NULL,  0 }
        };
	int option_index = 0;

    while (1) {
        c = getopt_long(argc, argv, "abc:d:",
                 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 '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 '?':
            break;

        default:
            printf("?? getopt returned character code 0%o ??\n", c);
        }
    }

    if (optind >= argc) {
        fprintf(stderr, "expected non-option argument\n");
        fprintf(stderr, "Usage:%s [-a][-b][-c xxx][-d xxx] [--add xxx][--append][--create xxx] arg\n", argv[0]);
        exit(EXIT_FAILURE);
    } else { /* optind < argc */
        printf("non-option arguments: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

    exit(EXIT_SUCCESS);
}

猜你喜欢

转载自blog.csdn.net/rikeyone/article/details/88864327