命令行参数解析函数 getopt, getopt_long, getopt_long_only

    • 所在头文件
    • 包含函数名和全局变量名
    • 大纲
    • 描述
    • 例子
      • getopt
      • getopt_long
    • 参考

所在头文件

#include

包含函数名和全局变量名

getopt 短参数解析函数,如 "-h" 解析
getopt_long 长短参数解析函数, '-'匹配短参数, "--"匹配长参数
getopt_long_only 只匹配长参数, 即'-'也只匹配长参数
optarg 参数值, 如 "--time-limit=100", optarg值为"100", 若不带值, optarg=NULL
optind 该参数在argc数组中的处于第几位, argc[optind-1]可以取到参数名字
opterr 整形,设置为0, 可以在输入错误参数时不报错. 设置为非0(默认), 在输入错误参数时会报错. 用于getopt函数
optopt 用于getopt函数, 当输入错误参数时, optopt保存了该错误参数,而getopt函数返回'?'

大纲

#include 

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

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

#include 

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);

描述

int getopt(int argc, char * const argv[], const char *optstring);
getopt()可以parse命令行参数, argc, argv分别对应main()中的argc和argv. 匹配argv中’-‘开头的元素, 返回值是参数字符的ASCII值.
此时optind是argv中下一个元素对应的下标, 初始值为1
如果getopt()发现了其他可匹配字符, 它将返回该字符,并且更新optind值. 直到没有新的可选字符时, getopt()返回-1, 此时optind是第一个非参数的argv元素的下标值
optstring描述了接受哪些短参数, 如果字符后面紧跟’:’, 说明该字符是带值的, 否则是不带值参数, 如 optstring = “abc:d:e:”, 其中不带值参数是”-a’, “-b”, “-e”, 带值参数是 “-c”, “-d”, 即 -a -c=100. optarg则保存参数的值, 如"-a=100", optarg="100"

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

getopt_longgetopt类似, 不过getopt_long可以接受短参数(以’-‘开始)和长参数(以”–”开始), 如果getopt_long只想接受长参数, 需要将optstring设置成 “”, 而不是NULL.

longopts是一个指针, 指向一个结构体数组, 结构体形式应该为

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

解释:
- name:
长参数的名字
- has_arg:
是否是必须字段
1. no_argument(or 0) 没有值的字段
2. required_argument(or 1) 必须字段
3. optional_argument(or 2) 可选字段
- flag
描述了getopt_long返回值内容, 如果flag设置成NULL, 那么getopt_long将返回val.(比如, 将val设置成一个短的可选参数).
- val
描述了getopt_long的返回值

例子

getopt

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    int flags, opt;
    int nsecs, tfnd;

    nsecs = 0;
    tfnd = 0;
    flags = 0;
    // 每次处理一个参数, 当opt = -1 时, 说明parse完成, 退出循环
    while ((opt = getopt(argc, argv, "nt:")) != -1) { 
        switch (opt) { // opt 类型为 int, 值为字符的ASCII值
        case 'n':
            flags = 1;
            break;
        case 't':
            nsecs = atoi(optarg); // optarg即 "-t=1234" 中 "1234"值
            tfnd = 1;
            break;
        default: /* '?' */  // 当遇到不在optstring的参数, opt='?'
            fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }

   printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);

   if (optind >= argc) {
        fprintf(stderr, "Expected argument after options\n");
        exit(EXIT_FAILURE);
    }

   printf("name argument = %s\n", argv[optind]); // parse后, 此时 optind指向第一个非参数命令行值

   /* Other code omitted */

   exit(EXIT_SUCCESS);
}

运行结果

$ ./a.out -t=142 asdf -n
flags=1; tfnd=1; optind=3
name argument = asdf

$ ./a.out -t=142 asdf
flags=0; tfnd=1; optind=2
name argument = asdf

getopt_long

#include      /* for printf */
#include     /* for exit */
#include 

int main(int argc, char **argv)
{
    int c;
    int digit_optind = 0;

   while (1) {
        int this_option_optind = optind ? optind : 1;
        int option_index = 0;
        // 定义结构体, 
        static struct option long_options[] = {
            {"add",     required_argument, NULL,  0 }, 
            {"append",  no_argument,       NULL,  0 },
            {"delete",  required_argument, NULL,  0 },
            {"verbose", no_argument,       NULL,  0 },
            // 当输入参数`--create`, getopt_long返回值为'c', 这样可以实现
            // "--create"和"-c"共享一段处理代码
            {"create",  required_argument, NULL, 'c'},  
            {"file",    required_argument, NULL,  0 },
            {0,         0,                 NULL,  0 }
        };

       c = getopt_long(argc, argv, "abc:d: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;
       // 处理参数 "--create" 和 "-c"
       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) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

   exit(EXIT_SUCCESS);
}

输出

$ ./a.out --create=apple -d=123 -a --add=ok --append
option c with value 'apple'
option d with value '=123'
option a
option add with arg ok
option append

参考

https://linux.die.net/man/3/getopt_long

你可能感兴趣的:(C++)