Skip to content

Latest commit

 

History

History
359 lines (323 loc) · 9.19 KB

200505090946.txt.md

File metadata and controls

359 lines (323 loc) · 9.19 KB

24.6 getopt()、getopt_long()、getopt_long_only()是何用法

Q: 能给一个getopt()的例子吗

A: 小四 [email protected] 1999-04-05 17:02


/*

  • For x86/Linux
  • gcc -Wall -pipe -O3 -s -o getopt_test getopt_test.c */

#include <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> #include <unistd.h>

#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 getopt() 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  = %u\n"
    "strvar  = %s\n",
    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: 小四 [email protected] 2001-12-17 15:30

这需要用到getopt_long(),但这不是一个具有良好可移植性的函数。


/*

  • For x86/Linux
  • gcc -Wall -pipe -O3 -s -o getopt_long_test getopt_long_test.c */

#include <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> #include <unistd.h> /*

  • 为了使用getopt_long(),必须有如下两行内容 */ #define _GNU_SOURCE #include <getopt.h>

#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  = %u\n"
    "strvar  = %s\n",
    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: 小四 [email protected] 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 <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> #include <unistd.h> /*

  • 为了使用getopt_long_only(),必须有如下两行内容 */ #define _GNU_SOURCE #include <getopt.h>

#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  = %u\n"
    "strvar  = %s\n",
    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