在程式中難免需要使用命令列選項,可以選擇自己解析命令列選項,但是有現成的,何必再造輪子。下面介紹使用getopt_long_only和getopt_long( 兩者用法差不多)解析命令列選項。
程式中主要使用:
短選項 |
長選項 |
是否需要參數 |
-n |
--username |
是(使用者名稱) |
指定使用者名稱 |
-d |
--debug |
否 |
是否已測試 |
1、函數出處
#include <getopt.h> //getopt_long()標頭檔位置 int getopt_long (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind); int getopt_long_only (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind);
2、參數介紹 argc argv :直接從main函數傳遞而來 shortopts:短選項字串。如”n:v",這裡需要指出的是,短選項字串不需要‘-’,而且但選項需要傳遞參數時,在短選項後面加上“:”。 longopts:struct option 數組,用於存放長選項參數。 longind:用於返回長選項在longopts結構體數組中的索引值,用於調試。一般置為NULL 下面介紹struct option
struct option { const char *name;//長選項名 int has_arg;//是否需要參數 int *flag; int val; };
name:長選項名字
has_arg:是否需要參數。值有三種情況
# define no_argument 0 //不需要參數 # define required_argument 1 //必須指定參數 # define optional_argument 2 //參數可選
flag和val相互依賴,主要分兩種情況: (1)、flag為NULL,val值用於確定該長選項,所以需要為長選項指定唯一的val值。這裡也為長選項和短選項建立了橋樑。 (2)、flag不為NULL,則將val值存放到flag所指向的儲存空間,用於標識該長選項出現過。
3、傳回值 程式中使用短選項,則返回短選項字元(如‘n'),當需要參數是,則在返回之前將參數存入到optarg中。 程式中使用長選項,傳回值根據flag和val確定。當flag為NULL,則返回val值。所以根據val值做不同的處理,這也說明了val必須唯一。當val值等於短選項值,則可以使用短選項解析函數解析長選項;當flag不為NULL,則將val值存入flag所指向的儲存空間,getopt_long返回0 出現未定義的長選項或者短選項,getopt_long返回。 解析完畢,getopt_long返回-1
4、執行個體 理論要與實際相結合
執行個體一:
#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; }
執行個體二:
#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,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;}
至於運行結果,我只給出用例,大家有興趣可以試試。
執行個體1:./test -n boy
執行個體2:./test -n boy