程序的參數(shù) 系統(tǒng)執(zhí)行一個(gè)C語(yǔ)言程序總是從main()函數(shù)開始。在標(biāo)準(zhǔn)的C程序中,,main()函數(shù)有兩個(gè)參數(shù),,它們代表程序的命令行參數(shù),,原型如下: int main(int argc, char *argv[]); argc是命令行參數(shù)的個(gè)數(shù),,argv是C字符串的數(shù)組,,它的元素是單個(gè)的命令行參數(shù)字符串,。執(zhí)行程序名是第一個(gè)字符串,,而所有參數(shù)之后總是一個(gè)NULL指針:argv[argc]總是NULL,。 比如,,命令“cat abc def”中,argc等于3,,argv的有效元素有3個(gè),,分別是cat、abc,、def,。 在UNIX系統(tǒng)中,可以定義三個(gè)參數(shù)的main函數(shù),,它的原型如下: int main(int argc, char *argv[], char *envy); 第三個(gè)參數(shù)是程序執(zhí)行的環(huán)境變量,,在稍后我們會(huì)講到。但是POSIX1不允許三個(gè)參數(shù)的形式,,所以,,最好采用兩個(gè)參數(shù)的main函數(shù)。 POSIX建議程序的選項(xiàng)(options)按照下面的規(guī)則定義: * 選項(xiàng)用連字符“-”開始,,并且只含有字符和數(shù)字,。 * 多選項(xiàng)可以合并寫出:-abc等于-a –b –c。 * 某些選項(xiàng)可以帶一個(gè)參數(shù)(argument),。如:-o file,。 * 帶參數(shù)選項(xiàng)一般位于其它無(wú)參數(shù)選項(xiàng)前面。 * 兩個(gè)連字符“--”之后所有的選項(xiàng)都視為普通命令行參數(shù),。 * 長(zhǎng)選項(xiàng)用“--”開始,,且不帶參數(shù)。由于長(zhǎng)選項(xiàng)沒(méi)有參數(shù),,可以用“--name=value”的形式給出參數(shù),。 如果你的程序參數(shù)少,可以直接從argv數(shù)組中獲取,。如果選項(xiàng)較多而復(fù)雜,,分析起來(lái)很麻煩,這時(shí)可以使用getopt()和getopt_long()函數(shù)分析典型的命令行參數(shù),。使用這兩個(gè)函數(shù),,必須包含unistd.h文件。 getopt函數(shù)的原型如下: int getopt(int argc, char **argv, const char *options); 該函數(shù)的作用是分析參數(shù)argc和argv提供的選項(xiàng)。這里的argc和argv往往直接來(lái)源于main函數(shù)的參數(shù),。options給出需要分析的有效選項(xiàng)的列表,,是以字符串的形式給出。其中需要有參數(shù)的選項(xiàng)后跟一個(gè)“:”,,如果參數(shù)是可選的,,則后面有兩個(gè)冒號(hào)“::”。 getopt函數(shù)返回命令行中的一個(gè)選項(xiàng)字符,,如果有參數(shù),,其參數(shù)存儲(chǔ)在預(yù)定義變量char* optarg指定的內(nèi)存中。如果參數(shù)列表argv中包含普通的不是選項(xiàng)的參數(shù),,或者包含不在options中指定的選項(xiàng),,則getopt函數(shù)返回“?”字符,,并且把相應(yīng)的字符存儲(chǔ)到變量optopt中,。如果這時(shí)外部變量opterr不等于0,則getopt函數(shù)會(huì)打印錯(cuò)誤信息,。當(dāng)所有選項(xiàng)都給出后,,函數(shù)返回-1,表示沒(méi)有選項(xiàng)了,。 通常getopt函數(shù)應(yīng)該在一個(gè)循環(huán)中調(diào)用,,每次給出一個(gè)選項(xiàng),直到返回-1,。循環(huán)中分析得到的選項(xiàng),,往往用switch語(yǔ)句。循環(huán)結(jié)束后,,往往還需要一個(gè)循環(huán)分析不是選項(xiàng)的命令行參數(shù),,首個(gè)不是選項(xiàng)的命令行參數(shù)的位置存儲(chǔ)在變量optind中。下面舉例如下: #include <unistd.h> #include <stdio.h> int main(int argc,char *argv[]) { int aflag = 0; int bflag = 0; char *cvalue = NULL; int index; int c; opterr = 0; while((c=getopt(argc,argv,"abc:"))!=-1) switch(c) { case 'a': aflag=1; break; case 'b': bflag=1; break; case 'c': cvalue=optarg; break; case '?': if(isprint(optopt)) fprintf(stderr,"Unknown option '-%c'.\n",optopt); else fprintf(stderr, "Unknown option charactor '\\x%x'.\n", optopt); return 1; default: abort(); } printf("aflag = %d, bflag = %d, cvalue = %s\n",aflag,bflag,cvalue); for(index=optind;index<argc;index++) printf("Non-option argument %s\n",argv[index]); return 0; } 函數(shù)getopt_long除了能夠處理普通選項(xiàng),,還能處理長(zhǎng)選項(xiàng),。它的原型如下: int getopt_long(int argc, char **argv, const char *shortopts, struct option *longopts, int *indexptr); 它從argv中解析出選項(xiàng)。參數(shù)shortopts描述了需要解析的短選項(xiàng),,它的表示方法同getopt函數(shù)一樣,,參數(shù)longopts描述了接受的長(zhǎng)選項(xiàng)。當(dāng)getopts_long函數(shù)遇到一個(gè)短選項(xiàng),,它的行為和getopts函數(shù)一樣:返回選項(xiàng)字符,,把參數(shù)存儲(chǔ)到optarg中。 結(jié)構(gòu)option是預(yù)先定義的結(jié)構(gòu),,用來(lái)表明函數(shù)getopts_long能夠接受的長(zhǎng)選項(xiàng)和對(duì)該長(zhǎng)選項(xiàng)的處理方法,。它包含如下4個(gè)成員: const char *name:字符串,,選項(xiàng)的名稱。 int has_arg:表示該長(zhǎng)選項(xiàng)是否包含參數(shù),。它可取值no_argument,、required_argument、optional_argument,,分別表示無(wú)參數(shù)、有參數(shù),、可選參數(shù),。 int *flag int val : 這兩個(gè)參數(shù)合起來(lái)表示處理該選項(xiàng)的方法。如果指針flag為NULL,,val就表示一個(gè)代表該選項(xiàng)的唯一整數(shù),。如果函數(shù)getopts_long的返回值是該整數(shù),表明找到了該選項(xiàng),。如果希望某個(gè)長(zhǎng)選項(xiàng)和另外一個(gè)短選項(xiàng)具有相同的意義,,可以定義該長(zhǎng)選項(xiàng)的val值和短選項(xiàng)字符相同。如果指針指向一個(gè)分配好的整數(shù),,那么當(dāng)找到該選項(xiàng)時(shí),,這個(gè)整數(shù)就用來(lái)存儲(chǔ)val給出的值,用來(lái)表明找到了該選項(xiàng),。這種情況下,,函數(shù)getopts_long返回0。 函數(shù)getopts_long的參數(shù)longopts是一個(gè)指向結(jié)構(gòu)option的指針,,給出一組option類型的長(zhǎng)選項(xiàng),,用{0,0,,0,,0}表示參數(shù)結(jié)束。 函數(shù)getopts_long的最后一個(gè)參數(shù)indexptr是一個(gè)整數(shù)指針,,它在函數(shù)getopts_long正確調(diào)用后被設(shè)置成當(dāng)前參數(shù)在longopts中的位置,。比如,你可以用longopts[*indexptr].name引用找到參數(shù)的名稱,。 如果長(zhǎng)選項(xiàng)有參數(shù),,它將被存儲(chǔ)到optarg變量中。如果沒(méi)有參數(shù),,變量optarg等于NULL,。 當(dāng)函數(shù)getopts_long不再能找出選項(xiàng)時(shí),它返回-1,。它仍然用optind表明剩下的參數(shù)在argv中的位置,。 下面舉例說(shuō)明。 #include <stdio.h> #include <stdlib.h> #include <getopt.h> /* Flag set by '--verbose'. */ static int verbose_flag; int main(int argc,char **argv) { int c; while(1) { static struct option long_options[]= { {"verbose",no_argument,&verbose_flag,1}, {"brief",no_argument,&verbose_flag,0}, {"add",required_argument,0,0}, {"append",no_argument,0,0}, {"delete",no_argument,0,0}, {"create",no_argument,0,0}, {"file",no_argument,0,0}, {0,0,0,0} }; int option_index = 0; c = getopt_long(argc,argv,"abc:d:", long_options,&option_index); if(c==-1) break; switch(c) { case 0: if(long_options[option_index].flag!=NULL) break; printf("option %s",long_options[option_index].name); if(optarg) printf(" with arg %s",optarg); printf("\n"); break; case 'a': puts("option -a\n"); break; case 'b': puts("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: abort(); } } if(verbose_flag) puts("verbose flag is set"); if(optind<argc) { printf("non-option argv elements: "); while(optind<argc) printf("%s ",argv[optind++]); putchar('\n'); } exit(0); } |
|