Live & Learn
分类: 嵌入式
2011-02-22 17:46:42
#include
#include
#include
#include
#include
#define VERSION "1.00 1999-04-05 17:02"
static void usage ( char *arg )
{
fprintf
(
stderr,
"Usage: %s [-h] [-v] [-i intvar] [-s strvar]n",
arg
);
exit( EXIT_FAILURE );
} /* end of usage */
int main ( int argc, char * argv[] )
{
int ret = EXIT_FAILURE;
int c;
unsigned int intvar = 0;
char *strvar = NULL;
if ( 1 == argc )
{
usage( argv[0] );
}
/*
* don't want () writing to stderr
*/
opterr = 0;
/*
* getopt()第三形参最前面如果有冒号,就不会出现illegal option错误信息。
* 不过,如果指定了"opterr = 0",有无这个前导冒号都无所谓了。
*/
while ( EOF != ( c = getopt( argc, argv, ":hi:s:v" ) ) )
{
switch ( c )
{
case 'i':
intvar = ( unsigned int )strtoul( optarg, NULL, 0 );
break;
case 's':
strvar = optarg;
break;
case 'v':
printf( "%s ver "VERSION"n", argv[0] );
return( EXIT_SUCCESS );
case 'h':
case '?':
default :
usage( argv[0] );
break;
} /* end of switch */
} /* end of while */
argc -= optind;
argv += optind;
printf
(
"intvar = %un"
"strvar = %sn",
intvar,
NULL == strvar ? "(null)" : strvar
);
ret = EXIT_SUCCESS;
return( ret );
} /* end of main */
#if 0
$ ./getopt_test -h
Usage: ./getopt_test [-h] [-v] [-i intvar] [-s strvar]
$ ./getopt_test -i 1314 -s scz
intvar = 1314
strvar = scz
$ ./getopt_test -v
./getopt_test ver 1.00 1999-04-05 17:02
#endif
--------------------------------------------------------------------------
Q: 现在会用getopt()了,但如何支持"--parami intvar --params strvar"呢
A: 小四 <scz@nsfocus.com> 2001-12-17 15:30
这需要用到getopt_long(),但这不是一个具有良好可移植性的函数。
--------------------------------------------------------------------------
/*
* For x86/Linux
* gcc -Wall -pipe -O3 -s -o getopt_long_test getopt_long_test.c
*/
#include
#include
#include
#include
#include
/*
* 为了使用getopt_long(),必须有如下两行内容
*/
#define _GNU_SOURCE
#include
#define VERSION "1.00 2001-12-17 15:30"
/*
* 不要与短选项所用的字符相同!
*/
#define LONGOPTIONCHAR '*'
static void usage ( char *arg )
{
fprintf
(
stderr,
"Usage: %s [-h] [--ver] [--parami intvar] [-params strvar]n",
arg
);
exit( EXIT_FAILURE );
} /* end of usage */
int main ( int argc, char * argv[] )
{
int ret = EXIT_FAILURE;
int c;
unsigned int intvar = 0;
char *strvar = NULL;
struct option longOption[] =
{
{ "ver", 0, NULL, LONGOPTIONCHAR },
{ "parami", 1, NULL, LONGOPTIONCHAR },
{ "params", 1, NULL, LONGOPTIONCHAR },
{ NULL, 0, NULL, 0 }
};
int longOptionIndex = 0;
if ( 1 == argc )
{
usage( argv[0] );
}
/*
* don't want getopt() writing to stderr
*/
opterr = 0;
while ( EOF != ( c = getopt_long( argc, argv, ":h", longOption, &longOptionIndex ) ) )
{
switch ( c )
{
case LONGOPTIONCHAR:
if ( optarg )
{
switch ( longOptionIndex )
{
case 1:
intvar = ( unsigned int )strtoul( optarg, NULL, 0 );
break;
case 2:
strvar = optarg;
break;
default:
break;
} /* end of switch */
}
else
{
switch ( longOptionIndex )
{
/*
* longOption[]的下标
*/
case 0:
printf( "%s ver "VERSION"n", argv[0] );
return( EXIT_SUCCESS );
default:
break;
} /* end of switch */
}
break;
case 'h':
case '?':
default :
usage( argv[0] );
break;
} /* end of switch */
} /* end of while */
argc -= optind;
argv += optind;
printf
(
"intvar = %un"
"strvar = %sn",
intvar,
NULL == strvar ? "(null)" : strvar
);
ret = EXIT_SUCCESS;
return( ret );
} /* end of main */
#if 0
$ ./getopt_long_test -h
Usage: ./getopt_long_test [-h] [--ver] [--parami intvar] [-params strvar]
$ ./getopt_long_test --parami 1314 --params scz
intvar = 1314
strvar = scz
$ ./getopt_long_test --ver
./getopt_long_test ver 1.00 2001-12-17 15:30
#endif
--------------------------------------------------------------------------
Q: 那getopt_long_only()与getopt_long()的区别是什么
A: 小四 <scz@nsfocus.com> 2005-05-09 10:48
getopt_long_only()的行为与getopt_long()非常类似,但不限于用'--'引入长选项,
'-'亦可引入长选项。当'-'引入的选项不匹配任何长选项时,继续进行短选项匹配。
再次提醒,getopt_long_only()与getopt_long()一样,不具有良好可移植性。
--------------------------------------------------------------------------
/*
* For x86/Linux
* gcc -Wall -pipe -O3 -s -o getopt_long_only_test getopt_long_only_test.c
*/
#include
#include
#include
#include
#include
/*
* 为了使用getopt_long_only(),必须有如下两行内容
*/
#define _GNU_SOURCE
#include
#define VERSION "1.00 2005-05-09 10:48"
/*
* 不要与短选项所用的字符相同!这次用空格符,更可靠些。
*/
#define LONGOPTIONCHAR ' '
static void usage ( char *arg )
{
fprintf
(
stderr,
"Usage: %s [-h] [--v] [-i intvar] [--s strvar]n",
arg
);
exit( EXIT_FAILURE );
} /* end of usage */
int main ( int argc, char * argv[] )
{
int ret = EXIT_FAILURE;
int c;
unsigned int intvar = 0;
char *strvar = NULL;
struct option longOption[] =
{
{ "v", 0, NULL, LONGOPTIONCHAR },
{ "s", 1, NULL, LONGOPTIONCHAR },
{ NULL, 0, NULL, 0 }
};
int longOptionIndex = 0;
if ( 1 == argc )
{
usage( argv[0] );
}
/*
* don't want getopt() writing to stderr
*/
opterr = 0;
while ( EOF != ( c = getopt_long_only( argc, argv, ":hi:", longOption, &longOptionIndex ) ) )
{
switch ( c )
{
case LONGOPTIONCHAR:
if ( optarg )
{
switch ( longOptionIndex )
{
case 1:
strvar = optarg;
break;
default:
break;
} /* end of switch */
}
else
{
switch ( longOptionIndex )
{
/*
* longOption[]的下标
*/
case 0:
printf( "%s ver "VERSION"n", argv[0] );
return( EXIT_SUCCESS );
default:
break;
} /* end of switch */
}
break;
case 'i':
intvar = ( unsigned int )strtoul( optarg, NULL, 0 );
break;
case 'h':
case '?':
default :
usage( argv[0] );
break;
} /* end of switch */
} /* end of while */
argc -= optind;
argv += optind;
printf
(
"intvar = %un"
"strvar = %sn",
intvar,
NULL == strvar ? "(null)" : strvar
);
ret = EXIT_SUCCESS;
return( ret );
} /* end of main */
#if 0
$ ./getopt_long_only_test -h
Usage: ./getopt_long_only_test [-h] [--v] [-i intvar] [--s strvar]
$ ./getopt_long_only_test --v
./getopt_long_only_test ver 1.00 2005-05-09 10:48
$ ./getopt_long_only_test -v
./getopt_long_only_test ver 1.00 2005-05-09 10:48
$ ./getopt_long_only_test -i 1314 -s scz
intvar = 1314
strvar = scz
#endif
行参数的分析
作者:Hoyt (2001-08-22 16:41:41)
在实际程序之中我们经常要对命令行参数进行分析. 比如我们有一个程序a可以接受许多参数.一个可能的情况是
a -d print --option1 hello --option2 world
那么我们如何对这个命令的参数进行分析了?.经常用函数是getopt和getopt_long.
#include
#include
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的扩展.getopt接受的命令行参数只可以是以(-)开头,而getopt_long还可以接受(--)开头的参数.一般以(-)开头的参数的标志只有一个字母,而以(--)开头的参数可以是一个字符串.如上面的 -d,--option1选项.
argc,和argv参数是main函数的参数.optstring指出了我们可以接受的参数.其一般的形式为:参数1[:]参数2[:].... 其中参数是我们可以接受的参数,如果后面的冒号没有省略,那么表示这个参数出现时后面必需要带参数值. 比如一个optstring为abc:d:表示这个参数选项可以为a,b,c,d其中c,d出现时候必须要有参数值.如果我们输入了一个我们没有提供的参数选项.系统将会说 不认识的 选项. getopt返回我们指定的参数选项.同时将参数值保存在optarg中,如果已经分析完成所有的参数函数返回-1.这个时候optind指出非可选参数的开始位置.
#include
#include
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[i]) printf(" with arg:%s\n",argv[i++]);
exit(0);
}
getopt_long比getopt复杂一点,不过用途要比getopt广泛.struct option 指出我们可以接受的附加参数选项.
name:指出长选项的名称(如我们的option1)
has_flag:为0时表示没有参数值,当为1的时候表明这个参数选项要接受一个参数值.为2时表示参数值可以有也可以没有.
指出函数的返回值.如果为NULL,那么返回val,否则返回0.并将longindex赋值为选项所在数组(longopts)的位置.
/* 这个是从 GNU Libc 手册上看到的 */
#include
#include
#include
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 选项 */
{"create", 0, 0, 'c'},
{"file", 1, 0, 0},
/* 数组结束 */
{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参数指出来的 */
case 'c':
printf ("option -c with value `%s'\n", optarg);
break;
case 'd':
printf ("option -d with value `%s'\n", optarg);
break;
}
}
exit (0);
}