c語言基礎之getopt()

getopt()

#include <unistd.h>

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

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

getopt()函數的做用:解析命令行參數。git

當命令行中的元素以"-"開頭,那麼該元素(argv[i])就是參數選項,其後的字符串就是參數。參數選項列表經過optstring指定。github

測試代碼以下:數組

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

int main(int argc, char** argv)
{
    int opt;
    printf("optind:%d\n", optind);

    opt = getopt(argc, argv, "ha:b::");

    printf("opt:%d\n", opt);
    printf("optarg:%s\n", optarg);
    printf("optind:%d\n", optind);

    return 0;
}

The variable optind is the index of the next element to be processed in argv. The system initializes this value to 1. The caller can reset it to 1 to restart scanning of the same argv, or when scanning a new argument vector.函數

optind 的值爲 argv中下一個待處理參數的索引值。optind的初始值爲1。調用者能夠將optind設置爲1,來從新掃描argv測試

pic1

圖1

從上圖能夠看出,optind的值爲3,即下一個參數的索引值。ui

optstringi is a string containing the legitimate option characters. If such a character is followed by a colon, the option requires an argument, so getopt() places a pointer to the following text in the same argv-element, or the text of the following argv-element, in optarg. Two colons mean an option takes an optional arg; if there is text in the current argv-element (i.e., in the same word as the option name itself, for example, "-oarg"), then it is returned in optarg, otherwise optarg is set to zero. This is a GNU extension.this

若是optstring中的字符後跟了一個冒號,那麼該字符表示參數選項,而且必需帶上參數(若是不帶參數,會有打印提示);同時optarg指向該參數,如圖1所示,optarg指向 參數選項(-a)的參數(abc)。spa

1559814496216

不帶參數,會有打印提示"./getopt_test: option requires an argument -- 'a' "命令行

1559814135508

參數選項和參數之間沒有空格分隔,也能正常解析。建議,參數選項和參數之間用空格分隔debug

若是optstring中的字符後跟了兩個冒號,那個該字符表示可選參數選項,若帶上參數,那麼optarg指向該參數;若沒有帶上參數,那麼optarg爲NULL;

1559814820735

兩冒號的參數選項,選項和參數之間必須連在一塊兒,不然,optarg獲取不到參數值。上圖中,-b參數選項是兩冒號的,當-b 與參數"qwe"之間有空格時,optarg爲NULL。

若是optstring中的字符後沒有跟冒號,那麼參數選項不須要帶參數。

1559813994041

上圖中,-h 是不帶參數選項,因此optarg指向NULL。

1559815762080

從上圖可知,getopt()是不支持long option。如須要支持long option,則要使用getopt_long()函數。

getopt_long()

#include <getopt.h>

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

The getopt_long() function works like getopt() except that it also accepts long options, started with two dashes. (If the program accepts only long options, then optstring should be specified as an empty string (""), not NULL.) Long option names may be abbreviated if the abbreviation is unique or is an exact match for some defined option. A long option may take a parameter, of the form --arg=param or --arg param.

getopt_long()的參數選項 是使用 two dashed("--")來指定。若是程序支持 長參數選項,須要將optstring設置爲空串("")。長選項參數的目的是爲了不參數產生歧義,只要不產生歧義,也能夠只用縮寫。

1559822622995

{"device", 2, &flag, 'd'},由上圖可知,--devi 因爲不會產生歧義,就做爲device處理;

\[longopts\] is a pointer to the first element of an array of struct option declared in <getopt.h> as

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

The meanings of the different fields are:

name is the name of the long option.

has_arg
is: no_argument (or 0) if the option does not take an argument; required_argument (or 1) if the option requires an argument; or optional_argument (or 2) if the option takes an optional argument.

flag specifies how results are returned for a long option. If flag is NULL, then getopt_long() returns val. (For example, the calling program may set val to the equivalent short option character.) Otherwise, getopt_long() returns 0, and flag points to a variable which is set to val if the option is found, but left unchanged if the option is not found.

val is the value to return, or to load into the variable pointed to by flag.

The last element of the array has to be filled with zeros.k

If longindex is not NULL, it points to a variable which is set to the index of the long option relative to longopts.

int main(int argc, char** argv)
{
    int c;
    int longindex = 0;
    int time = -1;

    struct option long_option[] =
    {
        {"help", 0, NULL, 'h'},
        {"time", 1, &time, 't'},
        {"device", 2, NULL, 'd'},
        {NULL, 0, NULL, 0},
    };

    c = getopt_long(argc, argv, "ht:d:", long_option, &longindex);

    printf("c:%d\n", c);
    printf("optarg:%s\n", optarg);
    printf("optind:%d\n", optind);
    printf("longindex:%d\n", longindex);
    printf("time=%d\n", time);

    return 0;
}

若是flag爲NULL,getopt_long()的返回值爲val(即對應的 短參數選項字符的值);若是指定了flag,getopt_long的返回值爲0,如有指定相應的option,則flag的值爲val。

1559821539388

指定了flag,getopt_long的返回值c等於0;flag變量time的值爲字符't'的值。longindex指向longopts數組的第一個元素。

1559821721634

flag爲NULL,getopt_long的返回值c等於字符'd'的值。

--arg=param和--arg param的區別

1559822037813

建議 使用 --arg=param 格式。

int main(int argc, char** argv)
{
    int ret = -1;
    int longindex = 0;

    struct option long_option[] =
    {
        {"help", 0, NULL, 'h'},
        {"time", 1, NULL, 't'},
        {"device", 2, NULL, 'd'},
        {"debug", 1, NULL, 'd'},
        {NULL, 0, NULL, 0},
    };

    while((ret = getopt_long(argc, argv, "ht:d:", long_option, &longindex)) >= 0)
    {
        switch(ret)
        {
        case 'h':
            printf("help\n");
            break;
        case 't':
            printf("optind:%d\n", optind);
            printf("longindex:%d\n", longindex);
            printf("time:%s\n", optarg);
            break;
        case 'd':
            printf("optind:%d\n", optind);
            printf("longindex:%d\n", longindex);
            if (0 == strcmp("device", long_option[longindex].name))
            {
                printf("device:%s\n", optarg); 
            }
            else if (0 == strcmp("debug", long_option[longindex].name))
            {
                printf("debug:%s\n", optarg); 
            }
            break;
        default:
            printf("?? getopt returned character code 0x%x ??\n", ret);
            break;
        }
    }

    return 0;
}

1559825107691

https://github.com/suonikeyinsuxiao/trunk/blob/master/libc/basic/usage/notes/getopt.md

相關文章
相關標籤/搜索