Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30103948
  • 博文数量: 230
  • 博客积分: 2868
  • 博客等级: 少校
  • 技术积分: 2223
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-08 21:48
个人简介

Live & Learn

文章分类

全部博文(230)

文章存档

2022年(2)

2019年(5)

2018年(15)

2017年(42)

2016年(24)

2015年(13)

2014年(1)

2012年(5)

2011年(58)

2010年(56)

2009年(9)

我的朋友

分类: 嵌入式

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);

 

阅读(3341) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~