getopt_long 函數


getopt_long, getopt_long_only -- 命令行解析函數,支持長選項解析
 
【說明】getopt_long/getopt_long_only是getopt的泛集,getopt是getopt_long的一個子集,getopt支持的所有特性,getopt_long都支持,包括錯誤打印、argv元素順序調整等;getopt_long相比getopt增加了長選項的解析,具體如下:
 
1、形如:cmd [--create][--file] //對長選項的解析;
2、形如:cmd [--create a_argument][-file b_argument] //對長選項及長選項的參數解析;
3、形如:cmd [--create [a_argument]] //選項create的參數也是可選的情況解析
getopt_long_only與getopt_long的區別在於:getopt_long僅僅只能將"--"開始的選項視為長選項,但getopt_long_only將"-"開頭選項也會視為長選項,當長選項列表均不滿足時,且短選項滿足時,"-"才會解析為短選項;
 
原型:
 
#define _GNU_SOURCE

#include <getopt.h>

 

extern char *optarg;

extern int optind, opterr, optopt;

 

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

描述:

 
1、注意相比getopt,使用getopt_long需要加頭文件 <getopt.h>;
2、getopt_long除了會接受長選項,其他概念和getopt是一樣的;
3、如果使用getopt_long想只接受短選項,設置longopts為NULL即可;如果只想接受長選項,相應地設置optstring為NULL即可;
4、長選項名是可以使用縮寫方式,比如:選項有--file\--create,那么輸入--c/--cr/--cre等均會被正確識別為create選項;
5、對於帶參數的長選項格式是:--arg=param或--arg param;
6、 longopts是指向struct option數組的第一個元素的指針,struct option定義在<getopt.h>中;
7、 longindex如果非NULL,則是返回識別到struct option數組中元素的位置指針;
 
struct option的說明:
 
/*
name: 長選項名
has_arg: 是否帶參數或可選參數,這個值在getopt.h中有宏定義,如下:
     # define no_argument        0
     # define required_argument  1
     # define optional_argument  2
flag: 確定函數返回值的情況,如果flag==NULL,則識別選項后返回val(常用的如:設置val為長命令的短命令字符);否則,識別后getopt_long返回0,flag指向一個設置到val的變量;
val: 設置為返回值,或者是flag指向的變量;這里要 注意不要寫-1到val,否則其作用是getopt_long返回-1,然后停止解析選項;
 
[注意] longopts的最后一個元素必須是全0填充,否則會報段錯誤
*/
 
struct option {
    const char *name; 
    int has_arg;  
    int *flag;
    int val;
};
 
返回值:
 
1、如果識別短選項,同getopt一樣返回短選項字符;
2、如果識別長選項,根據flag的設置返回不同的內容,一般flag都設置為NULL,返回val;
3、如果發生錯誤,如:未識別選項或者必須加參數的選項丟失參數,返回'?',如果在optstring中設置了第一個字符為':',丟失參數返回':',這個同getopt返回時一樣的;
4、當縮寫長選項引起歧義時或者不需要的選項強加了參數,都會返回'?';
5、返回-1表示選項處理全部結束;
6、如果在輸入的argv[]中包含了獨立的"--"字符串,同getopt一樣,解析到這里返回-1,停止選項的解析;
 
測試實例:
 
#include <stdio.h>

#include <stdlib.h>

#include <getopt.h>

 

int main(int argc, char **argv)

{

        extern char *optarg;

        extern int optind, opterr, optopt;

 

        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", required_argument, NULL, 'c'},

                        {"file", required_argument, NULL, 0},

                        {0, 0, 0, 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;

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

}

運行自行操作測試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM