函數getopt_long_only()

第一次接觸這個函數,是因爲學習mjpg-streamer的源碼。

函數作用:對命令行選項進行解析。

函數出處
頭文件getopt.h中:

#include <getopt.h>
int getopt_long_only(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

參數介紹
optstring:短選項字符串
longopts: struct option數組,用於存放長選項參數
longindex:用於返回長選項在longopts結構體數組的索引值,用於調試;一般置爲NULL

先介紹一下struct option

struct option {
    const char *name;          //長選項名
    int         has_arg;       //是否需要參數
    int        *flag;
    int         val;

};

參數has_arg的值:

# define no_argument                0       //if the option does not take an argument
# define required_argument      1        //if the option requires an argument

# define optional_argument      2        //if the option takes an optional argument

參數flag和val相互依賴,主要分兩種情況:
(1)flag爲NULL,val值用於確定該長選項,所以需要爲長選項指定唯一的val值。這裏也爲長選項和短選項建立了橋樑。
(2)flag不爲NULL,則將val值存放到flag所指向的存儲空間,用於標識該長選項出現過。

返回值
(1)短選項: 程序中使用短選項,則返回短選項字符(如‘n’),當需要參數時,則在返回之前將參數存入到optarg中。
(2)0/val值: 程序中使用長選項,返回值根據flag和val值確定。
①當flag爲NULL時,返回val值(所以根據val值做不同處理,即val必須唯一)。當val值等於短選項值,則可以使用短選項解析函數解析長選項。
②當flag不爲NULL時,則將val值存入flag所指向的存儲空間,getopt_long_only()返回0
(3)?: 出現未定義的長選項,函數返回“?”

(4)-1: 解析完所有參數之後返回-1(即當函數解析完參數返回-1之後跳出while循環)

實例
實例1:文件getopt.c源碼:

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h> //getopt_long()頭文件位置

int main(int argc, char** argv)
{
        const char *optstring = "n:v";
        int c, deb, index;
        struct option opts[] = {
                {"username", required_argument, NULL, 'n'},
                {"version", no_argument, NULL, 'v'},
                {"debug", no_argument, &deb, 1},
                {0,0,0,0}
        };

        while( (c = getopt_long_only(argc, argv, optstring, opts, &index)) != -1)
        {
                switch(c)
                {
                        case 'n':                   //使用-n 或者 --username 指定用戶名
                                printf("username is %s\n",optarg);
                                break;
                        case 'v':                  //使用-v 或者--version,輸出版本號
                                printf("version is 0.0.1 \n");
                                break;
                        case 0:                     //flag不爲NULL
                                printf("debug is %d\n",deb);
                                break;
                        case '?':                     //選項未定義
                                printf("?\n");
                                break;
                        default:
                                printf("c is %d\n",c);
                                break;
                }
        }
        return 0;
}

編譯運行結果分析:

$ ./getopt -n won
username is won         
$ ./getopt -v
version is 0.0.1
$ ./getopt -w
./getopt: unrecognized option '-w'
?
$ ./getopt -d
debug is 1

實例2:文件getopt_1.c源碼:(有點問題)

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

int main(int argc, char** argv)
{
        const char *optstring="n:v";
        int c,deb,index;
        struct option opts[]={
                {"username",required_argument,0,0},
                {"n",required_argument,0,0},
                {"version",no_argument,0,0},
                {"v",no_argument,0,0},
                {"debug",no_argument,0,0},
                {"d",no_argument,0,0},
                {"help",no_argument,0,0},
                {"h",no_argument,0,0}
        };

        while((c=getopt_long_only(argc,argv,optstring,opts,&index))!=-1)
        {
                switch(index){
                        //-n或者--username
                        case 0:
                        case 1:
                                printf("username:%s\n",optarg);
                                break;
                                //-v或者--version
                        case 2:
                        case 3:
                                printf("version:1.0.0\n");
                                break;
                                //-d or --debug
                        case 4:
                        case 5:
                                printf("debug:yes\n");
                                break;
                                //-h or --help
                        case 6:
                        case 7:
                                printf("Help:?\n");
                                break;
                        default:
                                printf("other:%d\n",index);
                                break;
                }
        }
        return 0;

}

執行結果分析:

$ ./getopt_1 --username won --version -d -h
username:won
version:1.0.0
debug:yes
Help:?

$ ./getopt_1 -j
Segmentation fault
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章