在編寫需要命令行參數的C程序的時候,往往我們需要先解析命令行參數,然后根據這些參數來啟動我們的程序。
C的庫函數中提供了兩個函數可以用來幫助我們解析命令行參數:getopt、getopt_long。
getopt可以解析短參數,所謂短參數就是指選項前只有一個“-”(如-t),而getopt_long則支持短參數跟長參數(如"--prefix")。
getopt函數
#include<unistd.h> int getopt(int argc,char * const argv[],const char *optstring);
extern char *optarg; //當前選項參數字串(如果有) extern int optind; //argv的當前索引值
各參數的意義:
argc:通常為main函數中的argc
argv:通常為main函數中的argv
optstring:用來指定選項的內容(如:"ab:c"),它由多個部分組成,表示的意義分別為:
1.單個字符,表示選項。
2 單個字符后接一個冒號:表示該選項后必須跟一個參數。參數緊跟在選項后或者以空格隔開。該參數的指針賦給optarg。
3 單個字符后跟兩個冒號,表示該選項后可以跟一個參數,也可以不跟。如果跟一個參數,參數必須緊跟在選項后不能以空格隔開。該參數的指針賦給optarg。
調用該函數將返回解析到的當前選項,該選項的參數將賦給optarg,如果該選項沒有參數,則optarg為NULL。下面將演示該函數的用法

1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 5 int main(int argc,char *argv[]) 6 { 7 int opt=0; 8 int a=0; 9 int b=0; 10 char s[50]; 11 while((opt=getopt(argc,argv,"ab:"))!=-1) 12 { 13 switch(opt) 14 { 15 case 'a':a=1;break; 16 case 'b':b=1;strcpy(s,optarg);break; 17 } 18 } 19 if(a) 20 printf("option a\n"); 21 if(b) 22 printf("option b:%s\n",s); 23 return 0; 24 }
編譯之后可以如下調用該程序
getopt_long函數
與getopt不同的是,getopt_long還支持長參數。
#include <getopt.h> int getopt_long(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex);
前面三個參數跟getopt函數一樣(解析到短參數時返回值跟getopt一樣),而長參數的解析則與longopts參數相關,該參數使用如下的結構
struct option { //長參數名 const char *name; /* 表示參數的個數 no_argument(或者0),表示該選項后面不跟參數值 required_argument(或者1),表示該選項后面一定跟一個參數 optional_argument(或者2),表示該選項后面的參數可選 */ int has_arg; //如果flag為NULL,則函數會返回下面val參數的值,否則返回0,並將val值賦予賦予flag所指向的內存 int *flag; //配合flag來決定返回值 int val; };
參數longindex,表示當前長參數在longopts中的索引值,如果不需要可以置為NULL。
下面是使用該函數的一個例子

1 #include <stdio.h> 2 #include <string.h> 3 #include <getopt.h> 4 5 int learn=0; 6 static const struct option long_option[]={ 7 {"name",required_argument,NULL,'n'}, 8 {"learn",no_argument,&learn,1}, 9 {NULL,0,NULL,0} 10 }; 11 12 int main(int argc,char *argv[]) 13 { 14 int opt=0; 15 while((opt=getopt_long(argc,argv,"n:l",long_option,NULL))!=-1) 16 { 17 switch(opt) 18 { 19 case 0:break; 20 case 'n':printf("name:%s ",optarg); 21 } 22 } 23 if(learn) 24 printf("learning\n"); 25 }
編譯之后可以如下調用該程序