参数的解析:getopt_long

getopt_long可以解析短参数(-a -b -c)和长参数(--add --delete --create),其定义在getopt.h中。

函数:
int getopt_long (int argc, char *const *argv, const char *shortopts, 
                 const struct option *longopts, int *indexptr)            

 

 参数:

  argv:需要解析的参数字符串

  argc:argv中字符串的数量

  shortopts: 支持的短参数的字符串

       longopts:   支持长参数的struct option集合

  indexptr:  *indexptr表明参数在longopts中的索引位置。

struct option
{
  const char *name;    //长参数名
  /* has_arg can't be an enum because some compilers complain about
     type mismatches in all the code that assumes it is an int.  */
  int has_arg;        //no_argument(0),required_argument(1),optional_argument(2)
int *flag; // 如果flag非NULL,则会将val保存至*flag中,当做标志。 int val; // 短参数名 };

 全局变量

        (1)optarg:表示当前选项对应的参数值。

        (2)optind:表示的是下一个将被处理到的参数在argv中的下标值。

        (3)optopt:表示没有被未标识的选项。

完整代码如下:

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

/* Flag set by ‘--verbose’. */
static int verbose_flag;
opterr = 1;
int main(int argc, char **argv)
{
    int c;
    static struct option long_options[] =
        {
            /* These options set a flag. */
            {"verbose1", no_argument, &verbose_flag, 1},
            {"verbose2", no_argument, &verbose_flag, 2},
            {"verbose3", no_argument, &verbose_flag, 3},
            {"brief", no_argument, &verbose_flag, 0},
            /* These options don’t set a flag.
             We distinguish them by their indices. */
            {"add", no_argument, 0, 'a'},
            {"append", no_argument, 0, 'b'},
            {"delete", required_argument, 0, 'd'},
            {"create", required_argument, 0, 'c'},
            {"file", required_argument, 0, 'f'},
            {0, 0, 0, 0}};
    /* getopt_long stores the option index here. */
    int option_index = 0;
    char shortOpt[512] = {0};
    int cnt = 0;
    for (int i = 0; i < sizeof(long_options) / sizeof(struct option); i++)
    {
        if (long_options[i].val >= 'a' && long_options[i].val <= 'z')
        {
            shortOpt[cnt++] = long_options[i].val;
            if (long_options[i].has_arg == required_argument)
            {
                shortOpt[cnt++] = ':';
            }
            else if (long_options[i].has_arg == optional_argument)
            {
                shortOpt[cnt++] = ':';
                shortOpt[cnt++] = ':';
            }
        }
    }
    printf("line: [%d] shortOpt[%s]\n", __LINE__, shortOpt);
    while (1)
    {

        c = getopt_long(argc, argv, shortOpt,
                        long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;
        printf("optind[%d],argc[%d]\n", optind, argc);
        printf("optarg=%s\n", optarg);
        if (optind < argc)
        {
            printf("next optarg=%s\n", argv[optind]);
        }

        switch (c)
        {
        case 0:
            /* If this option set a flag, do nothing else now. */
            if (long_options[option_index].flag != 0)
                break;
            printf("option %s", long_options[option_index].name);
            if (optarg)
                printf(" with arg %s", optarg);
            printf("\n");
            break;

        case 'a':
            puts("option -a\n");
            break;

        case 'b':
            puts("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 '?':
            /* getopt_long already printed an error message. */
            break;

        default:
            abort();
        }
    }

    /* Instead of reporting ‘--verbose’
     and ‘--brief’ as they are encountered,
     we report the final status resulting from them. */
    if (verbose_flag)
        printf("verbose flag is set:%d\n", verbose_flag);

    /* Print any remaining command line arguments (not options). */
    if (optind < argc)
    {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        putchar('\n');
    }

    exit(0);
}

 

 
posted @ 2020-12-05 13:46  稀里糊涂的胡闹  阅读(320)  评论(0)    收藏  举报