- 論壇徽章:
- 0
|
在實(shí)際程序之中我們經(jīng)常要對(duì)命令行參數(shù)進(jìn)行分析. 比如我們有一個(gè)程序 a 可以接受許多參數(shù).一個(gè)可能的情況是:
a -d print --option1 hello --option2 world
那么我們?nèi)绾螌?duì)這個(gè)命令的參數(shù)進(jìn)行分析? 經(jīng)常用的函數(shù)是 getopt 和 getopt_long.
#include unistd.h>
#include getopt.h>
int getopt(int argc,char const **argv, const char *optstring);
int getopt_long(int argc,char const **argc, const char *optstring,const struct option *longopts, int *longindex);
extern char *optarg;
extern int optind, opterr, optopt;
struct option {
char *name;
int has_flag;
int *flag;
int value;
};
getopt_long 是 getopt 的擴(kuò)展. getopt 接受的命令行參數(shù)只可以是以(-)開頭,
而 getopt_long 還可以接受(--)開頭的參數(shù). 一般以(-)開頭的參數(shù)的標(biāo)志只有一個(gè)字母,
而以(--)開頭的參數(shù)可以是一個(gè)字符串. 如上面的 -d,--option1 選項(xiàng).
argc 和 argv 參數(shù)是 main() 函數(shù)的參數(shù). optstring 指出了我們可以接受的參數(shù). 其一般的形式為: 參數(shù)1[:]參數(shù)2[:].... 其中參數(shù)是我們可以接受的參數(shù), 如果后面的冒號(hào)沒有省略, 那么表示這個(gè)參數(shù)出現(xiàn)時(shí)后面必需要帶參數(shù)值. 比如一個(gè) optstring 為 abc:d: 表示這個(gè)參數(shù)選項(xiàng)可以為 a, b, c, d 其中 c, d 出現(xiàn)時(shí)候必須要有參數(shù)值. 如果我們輸入了一個(gè)我們沒有提供的參數(shù)選項(xiàng), 系統(tǒng)將會(huì)說不認(rèn)識(shí)的選項(xiàng). getopt 返回我們指定的參數(shù)選項(xiàng), 同時(shí)將參數(shù)值保存在 optarg 中, 如果已經(jīng)分析完成所有的參數(shù)函數(shù)返回 -1.這個(gè)時(shí)候 optind 指出非可選參數(shù)的開始位置.
#include stdio.h>
#include unistd.h>
int main(int argc,char **argv)
{
int is_a,is_b,is_c,is_d,i;
char *a_value,*b_value,*c_value,temp;
is_a=is_b=is_c=is_d=0;
a_value=b_value=c_value=NULL;
if(argc==1)
{
fprintf(stderr,"Usage:%s [-a value] [-b value] [-c value] [-d] arglist ...\n",
argv[0]);
exit(1);
}
while((temp=getopt(argc,argv,"a:b:c:d"))!=-1)
{
switch (temp)
{
case @#a@#:
is_a=1;
a_value=optarg;
break;
case @#b@#:
is_b=1;
b_value=optarg;
break;
case @#c@#:
is_c=1;
c_value=optarg;
break;
case @#d@#:
is_d=1;
break;
}
}
printf("Option has a:%s with value:%s\n",is_a?"YES":"NO",a_value);
printf("Option has b:%s with value:%s\n",is_b?"YES":"NO",b_value);
printf("Option has c:%s with value:%s\n",is_c?"YES":"NO",c_value);
printf("OPtion has d:%s\n",is_d?"YES":"NO");
i=optind;
while(argv) printf(" with arg:%s\n",argv[i++]);
exit(0);
}
getopt_long 比 getopt 復(fù)雜一點(diǎn), 不過用途要比 getopt 廣泛.
struct option 指出我們可以接受的附加參數(shù)選項(xiàng).
name 指出長(zhǎng)選項(xiàng)的名稱(如我們的 option1 )
has_flag 為 0 時(shí)表示沒有參數(shù)值, 當(dāng)為 1 的時(shí)候表明這個(gè)參數(shù)選項(xiàng)要接受一個(gè)參數(shù)值. 為 2 時(shí)表示參數(shù)值可以有也可以沒有. 指出函數(shù)的返回值. 如果為NULL, 那么返回 val, 否則返回 0, 并將 longindex 賦值為選項(xiàng)所在數(shù)組(longopts)的位置.
/* 這個(gè)實(shí)例是從 GNU Libc 手冊(cè)上看到的 */
#include stdio.h>
#include stdlib.h>
#include getopt.h>
int main (int argc, char **argv)
{
int c;
while (1)
{
struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
/* 返回字符c,等同于 -c 選項(xiàng) */
{"create", 0, 0, @#c@#},
{"file", 1, 0, 0},
/* 數(shù)組結(jié)束 */
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "abc:d:",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s\n", optarg);
break;
case @#a@#:
puts ("option -a\n");
break;
case @#b@#:
puts ("option -b\n");
break;
/* 可能是-c --creat參數(shù)指出來的 */
case @#c@#:
printf ("option -c with value `%s@#\n", optarg);
break;
case @#d@#:
printf ("option -d with value `%s@#\n", optarg);
break;
}
}
exit (0);
}
當(dāng)我們輸入了錯(cuò)誤的選項(xiàng)后, 系統(tǒng)會(huì)給出錯(cuò)誤的提示, 如果我們想屏蔽這個(gè)信息, 我們可以設(shè)置 opterr 為 0, 對(duì)于錯(cuò)誤的選項(xiàng), 函數(shù)分析時(shí)候返回一個(gè)@#?@#字符. 我們可以自己對(duì)這個(gè)字符進(jìn)行處理.
本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u1/53296/showart_548198.html |
|