首页 > 编程语言 >C++参数解析参数

C++参数解析参数

时间:2023-11-04 10:24:45浏览次数:41  
标签:__ option int C++ optind 参数 argv getopt 解析

《C/C++参数解析》

1. getopt库的使用

  getopt用于解析程序命令行输入的参数,可解析短参数和长参数;解析短参数使用getopt()函数,解析长参数可使用getopt_long();

1.1 getopt()解析短参数

  getopt()函数用来解析短参数,例如-a或者-b 100这样的参数,不能解析长参数,如--ip 198.11.23.45这样的参数;

函数原型:

int getopt(int argc, char * const argv[], const char *optstring);

// -- optstring: 选项字符串,告知getopt()可以处理哪些参数选项以及哪些参数选项有参数值

optstring参数详解:

const char* optstring = "ab:c::";
参数 含义 格式
a 单个字符a, 表示参数选项a可有可无,有的话不能加参数值, -a
b: 单个字符加上冒号,表示参数选项b可有可无,如果有的话必须加参数值 -b100
c:: 单个字符加上两个冒号,表示参数c可以有,也可以无,
有的话既可以加参数,也可以不加参数 (没参数的时候optarg==NULL)
-c100

在getopt函数接收到optstring参数后,会依次检查参数a,b,c是否被传入,当对应的参数被指定以后,就会返回对应的参数名,如果参数带有值的话,可通过以下方法获取参数的值 (getopt提供了一些全局变量,可通过这些全局变量来获取参数值):

  • optarg 指向当前参数的值的指针,NULL时表示参数选项没有值
  • optind —— 用来记录argv中下一个检索的位置。
  • optopt —— 存储不在选项字符串optstring中的参数。
  • opterr ­—— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可

getopt()函数在命令解析完毕时候,会返回-1,如果解析到选项参数字符串中没有的参数,则会返回'?'.

示例代码:

#include <stdio.h>
#include "getopt.h"

int main(int argc, char** argv)
{
    opterr = 0;     // 是否输出错误信息
    int opt = 0;
    char const *optStr = "a::b:c";
    while ((opt=getopt(argc, argv, optStr)) != -1)
    {
        if (opt == 'a')  //可选参数,可传入或者不传入参数值
        {
            printf("Parameter a is get.\n");

            if (optarg==NULL)
                printf("No value");
            else
                printf("Value is %s", (char*)optarg);
        }
        else if (opt == 'b')   // 可选参数,必须传入参数值
        {
            printf("Parameter b is %s.\n", (char*)optarg);
        }
        else if (opt == 'c')   // 可选参数,不需要参数值
        {
            printf("Parameter c is get.\n");
        }
        else if (opt == '?')   // 未知参数,打印参数值  
        {
            printf("unknown para %c.\n", (char)optopt);
        }
    }

    return 0;
}

1.2 解析长参数

  getopt_long()包含了getopt()的功能,且可以解析长参数;

函数原型:

int getopt_long(int argc, char * const argv[], const char *optstring,
                         const struct option *longopts, int *longindex);

函数参数:

  • optstring 选项参数名
  • longopts 选项参数列表 (结构体)
  • longindex

longopts的类型为struct option,其定义如下所示:

// longopts指明了长参数的名称和属性,它是一个结构体指针
// 通常传一个结构体数组进去,每个元素代表一个参数,每个参数都是由下面的结构组成。

struct option 
{
   const char  *name;       /* 选项参数名称 */
   int          has_arg;    /* 指明选项参数是否带有参数值 0/1/2 */
   int          *flag;      
   int          val;        
};

// name:  选项参数的参数名
// has_arg: 选项参数是否有参数值 0/1/2 --> 无,有,可选
// *flag : 为NULL时,getopt_long()函数会返回val中指定的值作为选项标识;否则,getopt_long()函数会将val中指定的标识值存储在flag指向的内存中,且返回0。
// val: 指定选项的标识(int)
// longindex  如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。即符合条件的长选项的下标值

长参数的格式建议写为:

--reqarg1=werc16这种格式;避免出错;

代码示例:

#include <stdio.h>
#include "getopt.h"

// 定义长选项的标识
#define START_MODE_1   1
#define START_MODE_2   2
#define START_MODE_3   3

int main(int argc, char** argv)
{
    opterr = 1;     // 是否输出错误信息
    int opt = 0;
    char const *optStr = "a::b:c";

    // flag 为NULL, START_MODE直接由getopt_long()函数返回
    struct option longoptions[] = {
            {"reqarg1", required_argument, NULL, START_MODE_1},
            {"reqarg2", no_argument,       NULL, START_MODE_2},
            {"reqarg3", optional_argument, NULL, START_MODE_3}
    };

    while ((opt = getopt_long(argc, argv, optStr, longoptions, NULL)) != -1)
    {
        // 长参数处理
        if (opt == START_MODE_1)
        {
            printf("Start on mode 1 with para: %s.\n", (char*)optarg);
        }
        else if (opt == START_MODE_2)
        {
            printf("Start on mode 2.\n");
        }
        else if (opt == START_MODE_3)
        {
            if (optarg == NULL)
            {
                printf("Start on mode 3.\n");
            }
            else
            {
                printf("Start on mode 3 with para %s.\n", (char*)optarg);
            }
        }
        // 短参数处理
        else if (opt == 'a')  //可选参数,可传入或者不传入参数值
        {
            printf("Parameter a is get.\n");

            if (optarg==NULL)
                printf("No value");
            else
                printf("Value is %s", (char*)optarg);
        }
        else if (opt == 'b')   // 可选参数,必须传入参数值
        {
            printf("Parameter b is %s.\n", (char*)optarg);
        }
        else if (opt == 'c')   // 可选参数,不需要参数值
        {
            printf("Parameter c is get.\n");
        }
        else if (opt == '?')   // 未知参数,打印参数值  
        {
            printf("unknown para %c.\n", (char)optopt);
        }
    }

    return 0;
}

测试,flag设置为非空:

#include <stdio.h>
#include "getopt.h"

// 定义长选项的标识
#define START_MODE_1   1
#define START_MODE_2   2
#define START_MODE_3   3

int main(int argc, char** argv)
{
    opterr = 1;     // 是否输出错误信息
    int opt = 0;
    char const *optStr = "a::b:c";

    int cmd_code = 0;

    // flag 不为NULL, START_MODE的值会存储在cmd_code中;
    struct option longoptions[] = {
            {"reqarg1", required_argument, &cmd_code, START_MODE_1},
            {"reqarg2", no_argument,       &cmd_code, START_MODE_2},
            {"reqarg3", optional_argument, &cmd_code, START_MODE_3}
    };

    while ((opt = getopt_long(argc, argv, optStr, longoptions, NULL)) != -1)
    {
        if (cmd_code == START_MODE_1)
        {
            printf("Start on mode 1 with para: %s.\n", (char*)optarg);
        }
        else if (cmd_code == START_MODE_2)
        {
            printf("Start on mode 2.\n");
        }
        else if (cmd_code == START_MODE_3)
        {
            if (optarg == NULL)
            {
                printf("Start on mode 3.\n");
            }
            else
            {
                printf("Start on mode 3 with para %s.\n", (char*)optarg);
            }
        }
    }

    return 0;
}

1.3 解析长参数

   getopt_long_only()函数也可用来解析长参数;但是与getopt_long()函数有区别;getopt_long()函数会将-namre当作短参数来解为-n -a -m -e,而getopt_long_only会将-name和--name都当作长参数来解析;

2. getopt()源代码

  为解决getopt()能够跨平台使用,从网上找到经过修改的getopt源码,可将其编译成不同平台的库,实现跨平台使用。

2.1 getopt.h文件
# ifndef __GETOPT_H_
# define __GETOPT_H_
 
# ifdef _GETOPT_API
#     undef _GETOPT_API
# endif
//------------------------------------------------------------------------------
# if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
#     error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT \
can only be used individually"
# elif defined(STATIC_GETOPT)
#     pragma message("Warning static builds of getopt violate the Lesser GNU \
Public License")
#     define _GETOPT_API
# elif defined(EXPORTS_GETOPT)
#     pragma message("Exporting getopt library")
#     define _GETOPT_API __declspec(dllexport)
# else
#     pragma message("Importing getopt library")
#     define _GETOPT_API __declspec(dllimport)
# endif
 
# include <tchar.h>
// Standard GNU options
# define null_argument           0 /*Argument Null*/
# define no_argument             0 /*Argument Switch Only*/
# define required_argument       1 /*Argument Required*/
# define optional_argument       2 /*Argument Optional*/
// Shorter Versions of options
# define ARG_NULL 0 /*Argument Null*/
# define ARG_NONE 0 /*Argument Switch Only*/
# define ARG_REQ  1 /*Argument Required*/
# define ARG_OPT  2 /*Argument Optional*/
// Change behavior for C\C++
# ifdef __cplusplus
#     define _BEGIN_EXTERN_C extern "C" {
#     define _END_EXTERN_C }
#     define _GETOPT_THROW throw()
# else
#     define _BEGIN_EXTERN_C
#     define _END_EXTERN_C
#     define _GETOPT_THROW
# endif
_BEGIN_EXTERN_C
extern _GETOPT_API TCHAR *optarg;
extern _GETOPT_API int    optind;
extern _GETOPT_API int    opterr;
extern _GETOPT_API int    optopt;
struct option
{
/* The predefined macro variable __STDC__ is defined for C++, and it has the in-
   teger value 0 when it is used in an #if statement, indicating that the C++ l-
   anguage is not a proper superset of C, and that the compiler does not confor-
   m to C. In C, __STDC__ has the integer value 1. */
# if defined (__STDC__) && __STDC__
    const TCHAR* name;
# else
    TCHAR* name;
# endif
    int has_arg;
    int *flag;
    TCHAR val;
};
extern _GETOPT_API int getopt( int argc, TCHAR *const *argv
                             , const TCHAR *optstring ) _GETOPT_THROW;
extern _GETOPT_API int getopt_long
                             ( int ___argc, TCHAR *const *___argv
                             , const TCHAR *__shortopts
                             , const struct option *__longopts
                             , int *__longind ) _GETOPT_THROW;
extern _GETOPT_API int getopt_long_only
                             ( int ___argc, TCHAR *const *___argv
                             , const TCHAR *__shortopts
                             , const struct option *__longopts
                             , int *__longind ) _GETOPT_THROW;
// harly.he add for reentrant 12.09/2013
extern _GETOPT_API void getopt_reset() _GETOPT_THROW;
_END_EXTERN_C
// Undefine so the macros are not included
# undef _BEGIN_EXTERN_C
# undef _END_EXTERN_C
# undef _GETOPT_THROW
# undef _GETOPT_API
# endif  // __GETOPT_H_

2.2 getopt.cpp文件

# ifndef _CRT_SECURE_NO_WARNINGS
#     define _CRT_SECURE_NO_WARNINGS
# endif
 
# include <stdlib.h>
# include <stdio.h>
# include <tchar.h>
# include "getopt.h"
 
# ifdef __cplusplus
#     define _GETOPT_THROW throw()
# else
#     define _GETOPT_THROW
# endif
 
enum ENUM_ORDERING
{
    REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
};
 
struct _getopt_data
{
    int     optind;
    int     opterr;
    int     optopt;
    TCHAR*  optarg;
    int     __initialized;
    TCHAR*  __nextchar;
    int     __ordering;
    int     __posixly_correct;
    int     __first_nonopt;
    int     __last_nonopt;
};
static struct _getopt_data  getopt_data = { 0, 0, 0, NULL, 0, NULL, 0, 0, 0, 0 };
 
TCHAR*  optarg  = NULL;
int     optind  = 1;
int     opterr  = 1;
int     optopt  = _T( '?' );
 
static void exchange( TCHAR** argv, struct _getopt_data* d )
{
    int     bottom  = d->__first_nonopt;
    int     middle  = d->__last_nonopt;
    int     top     = d->optind;
    TCHAR*  tem;
    while ( top > middle && middle > bottom )
    {
        if ( top - middle > middle - bottom )
        {
            int len = middle - bottom;
            register int i;
            for ( i = 0; i < len; i++ )
            {
                tem = argv[bottom + i];
                argv[bottom + i] = argv[top - ( middle - bottom ) + i];
                argv[top - ( middle - bottom ) + i] = tem;
            }
            top -= len;
        }
        else
        {
            int len = top - middle;
            register int i;
            for ( i = 0; i < len; i++ )
            {
                tem = argv[bottom + i];
                argv[bottom + i] = argv[middle + i];
                argv[middle + i] = tem;
            }
            bottom += len;
        }
    }
    d->__first_nonopt += ( d->optind - d->__last_nonopt );
    d->__last_nonopt = d->optind;
}
 
static const TCHAR* _getopt_initialize( const TCHAR* optstring
                                      , struct _getopt_data* d
                                      , int posixly_correct )
{
    d->__first_nonopt = d->__last_nonopt = d->optind;
    d->__nextchar = NULL;
    d->__posixly_correct = posixly_correct
                         | !!_tgetenv( _T( "POSIXLY_CORRECT" ) );
    if ( optstring[0] == _T( '-' ) )
    {
        d->__ordering = RETURN_IN_ORDER;
        ++optstring;
    }
    else if ( optstring[0] == _T( '+' ) )
    {
        d->__ordering = REQUIRE_ORDER;
        ++optstring;
    }
    else if ( d->__posixly_correct )
    {
        d->__ordering = REQUIRE_ORDER;
    }
    else
    {
        d->__ordering = PERMUTE;
    }
    return optstring;
}
 
int _getopt_internal_r( int argc
                      , TCHAR *const * argv
                      , const TCHAR* optstring
                      , const struct option* longopts
                      , int* longind
                      , int long_only
                      , struct _getopt_data* d
                      , int posixly_correct )
{
    int print_errors    = d->opterr;
    if ( argc < 1 )
    {
        return -1;
    }
    d->optarg = NULL;
    if ( d->optind == 0 || !d->__initialized )
    {
        if ( d->optind == 0 )
        {
            d->optind = 1;
        }
        optstring = _getopt_initialize( optstring, d, posixly_correct );
        d->__initialized = 1;
    }
    else if ( optstring[0] == _T( '-' ) || optstring[0] == _T( '+' ) )
    {
        optstring++;
    }
    if ( optstring[0] == _T( ':' ) )
    {
        print_errors = 0;
    }
    if ( d->__nextchar == NULL || *d->__nextchar == _T( '\0' ) )
    {
        if ( d->__last_nonopt > d->optind )
        {
            d->__last_nonopt = d->optind;
        }
        if ( d->__first_nonopt > d->optind )
        {
            d->__first_nonopt = d->optind;
        }
        if ( d->__ordering == PERMUTE )
        {
            if ( d->__first_nonopt != d->__last_nonopt
              && d->__last_nonopt != d->optind )
            {
                exchange( ( TCHAR * * ) argv, d );
            }
            else if ( d->__last_nonopt != d->optind )
            {
                d->__first_nonopt = d->optind;
            }
            while ( d->optind
                  < argc
                 && ( argv[d->optind][0] != _T( '-' )
                   || argv[d->optind][1] == _T( '\0' ) ) )
            {
                d->optind++;
            }
            d->__last_nonopt = d->optind;
        }
        if ( d->optind != argc && !_tcscmp( argv[d->optind], _T( "--" ) ) )
        {
            d->optind++;
            if ( d->__first_nonopt != d->__last_nonopt
              && d->__last_nonopt != d->optind )
            {
                exchange( ( TCHAR * * ) argv, d );
            }
            else if ( d->__first_nonopt == d->__last_nonopt )
            {
                d->__first_nonopt = d->optind;
            }
            d->__last_nonopt = argc;
            d->optind = argc;
        }
        if ( d->optind == argc )
        {
            if ( d->__first_nonopt != d->__last_nonopt )
            {
                d->optind = d->__first_nonopt;
            }
            return -1;
        }
        if ( ( argv[d->optind][0] != _T( '-' )
            || argv[d->optind][1] == _T( '\0' ) ) )
        {
            if ( d->__ordering == REQUIRE_ORDER )
            {
                return -1;
            }
            d->optarg = argv[d->optind++];
            return 1;
        }
        d->__nextchar = ( argv[d->optind]
                        + 1 + ( longopts != NULL
                             && argv[d->optind][1] == _T( '-' ) ) );
    }
    if ( longopts != NULL
        && ( argv[d->optind][1] == _T( '-' )
            || ( long_only && ( argv[d->optind][2]
                                || !_tcschr( optstring, argv[d->optind][1] ) )
               )
           )
        )
    {
        TCHAR*                  nameend;
        const struct option*    p;
        const struct option*    pfound      = NULL;
        int                     exact       = 0;
        int                     ambig       = 0;
        int                     indfound    = -1;
        int                     option_index;
        for ( nameend = d->__nextchar;
              *nameend && *nameend != _T( '=' );
              nameend++ )
            ;
        for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
        {
            if ( !_tcsncmp( p->name, d->__nextchar, nameend - d->__nextchar ) )
            {
                if ( ( unsigned int ) ( nameend - d->__nextchar )
                  == ( unsigned int ) _tcslen( p->name ) )
                {
                    pfound = p;
                    indfound = option_index;
                    exact = 1;
                    break;
                }
                else if ( pfound == NULL )
                {
                    pfound = p;
                    indfound = option_index;
                }
                else if ( long_only
                       || pfound->has_arg != p->has_arg
                       || pfound->flag != p->flag
                       || pfound->val != p->val )
                {
                         ambig = 1;
                }
            }
        }
        if ( ambig && !exact )
        {
            if ( print_errors )
            {
                _ftprintf( stderr
                         , _T( "%s: option '%s' is ambiguous\n" )
                         , argv[0]
                         , argv[d->optind] );
            }
            d->__nextchar += _tcslen( d->__nextchar );
            d->optind++;
            d->optopt = 0;
            return _T( '?' );
        }
        if ( pfound != NULL )
        {
            option_index = indfound;
            d->optind++;
            if ( *nameend )
            {
                if ( pfound->has_arg )
                {
                    d->optarg = nameend + 1;
                }
                else
                {
                    if ( print_errors )
                    {
                        if ( argv[d->optind - 1][1] == _T( '-' ) )
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '--%s' doesn't allow " )
                                       _T( "an argument\n" )
                                     , argv[0]
                                     , pfound->name );
                        }
                        else
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '%c%s' doesn't allow " )
                                       _T( "an argument\n" )
                                     , argv[0]
                                     , argv[d->optind - 1][0]
                                     , pfound->name );
                        }
                    }
                    d->__nextchar += _tcslen( d->__nextchar );
                    d->optopt = pfound->val;
                    return _T( '?' );
                }
            }
            else if ( pfound->has_arg == 1 )
            {
                if ( d->optind < argc )
                {
                    d->optarg = argv[d->optind++];
                }
                else
                {
                    if ( print_errors )
                    {
                        _ftprintf( stderr
                                 , _T( "%s: option '--%s' requires an " )
                                   _T( "argument\n" )
                                 , argv[0]
                                 , pfound->name );
                    }
                    d->__nextchar += _tcslen( d->__nextchar );
                    d->optopt = pfound->val;
                    return optstring[0] == _T( ':' ) ? _T( ':' ) : _T( '?' );
                }
            }
            d->__nextchar += _tcslen( d->__nextchar );
            if ( longind != NULL )
            {
                *longind = option_index;
            }
            if ( pfound->flag )
            {
                *( pfound->flag ) = pfound->val;
                return 0;
            }
            return pfound->val;
        }
        if ( !long_only
          || argv[d->optind][1]
          == _T( '-' )
          || _tcschr( optstring
                    , *d->__nextchar )
          == NULL )
        {
            if ( print_errors )
            {
                if ( argv[d->optind][1] == _T( '-' ) )
                {
                    /* --option */
                    _ftprintf( stderr
                             , _T( "%s: unrecognized option '--%s'\n" )
                             , argv[0]
                             , d->__nextchar );
                }
                else
                {
                    /* +option or -option */
                    _ftprintf( stderr
                             , _T( "%s: unrecognized option '%c%s'\n" )
                             , argv[0]
                             , argv[d->optind][0]
                             , d->__nextchar );
                }
            }
            d->__nextchar = ( TCHAR * ) _T( "" );
            d->optind++;
            d->optopt = 0;
            return _T( '?' );
        }
    }
    {
        TCHAR   c       = *d->__nextchar++;
        TCHAR*  temp    = ( TCHAR* ) _tcschr( optstring, c );
        if ( *d->__nextchar == _T( '\0' ) )
        {
            ++d->optind;
        }
        if ( temp == NULL || c == _T( ':' ) || c == _T( ';' ) )
        {
            if ( print_errors )
            {
                _ftprintf( stderr
                         , _T( "%s: invalid option -- '%c'\n" )
                         , argv[0]
                         , c );
            }
            d->optopt = c;
            return _T( '?' );
        }
        if ( temp[0] == _T( 'W' ) && temp[1] == _T( ';' ) )
        {
            TCHAR*                  nameend;
            const struct option*    p;
            const struct option*    pfound      = NULL;
            int                     exact       = 0;
            int                     ambig       = 0;
            int                     indfound    = 0;
            int                     option_index;
            if ( *d->__nextchar != _T( '\0' ) )
            {
                d->optarg = d->__nextchar;
                d->optind++;
            }
            else if ( d->optind == argc )
            {
                if ( print_errors )
                {
                    _ftprintf( stderr
                             , _T( "%s: option requires an argument -- '%c'\n" )
                             , argv[0]
                             , c );
                }
                d->optopt = c;
                if ( optstring[0] == _T( ':' ) )
                {
                    c = _T( ':' );
                }
                else
                {
                    c = _T( '?' );
                }
                return c;
            }
            else
            {
                d->optarg = argv[d->optind++];
            }
            for ( d->__nextchar = nameend = d->optarg;
                  *nameend && *nameend != _T( '=' );
                  nameend++ )
                ;
            for ( p = longopts, option_index = 0;
                  p->name;
                  p++, option_index++ )
            {
                if ( !_tcsncmp( p->name
                              , d->__nextchar
                              , nameend - d->__nextchar ) )
                {
                    if ( ( unsigned int ) ( nameend - d->__nextchar )
                      == _tcslen( p->name ) )
                    {
                        pfound = p;
                        indfound = option_index;
                        exact = 1;
                        break;
                    }
                    else if ( pfound == NULL )
                    {
                        pfound = p;
                        indfound = option_index;
                    }
                    else if ( long_only
                           || pfound->has_arg != p->has_arg
                           || pfound->flag != p->flag
                           || pfound->val != p->val )
                    {
                             ambig = 1;
                    }
                }
            }
            if ( ambig && !exact )
            {
                if ( print_errors )
                {
                    _ftprintf( stderr
                             , _T( "%s: option '-W %s' is ambiguous\n" )
                             , argv[0]
                             , d->optarg );
                }
                d->__nextchar += _tcslen( d->__nextchar );
                d->optind++;
                return _T( '?' );
            }
            if ( pfound != NULL )
            {
                option_index = indfound;
                if ( *nameend )
                {
                    if ( pfound->has_arg )
                    {
                        d->optarg = nameend + 1;
                    }
                    else
                    {
                        if ( print_errors )
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '-W %s' doesn't allow " )
                                       _T( "an argument\n" )
                                     , argv[0]
                                     , pfound->name );
                        }
                        d->__nextchar += _tcslen( d->__nextchar );
                        return _T( '?' );
                    }
                }
                else if ( pfound->has_arg == 1 )
                {
                    if ( d->optind < argc )
                    {
                        d->optarg = argv[d->optind++];
                    }
                    else
                    {
                        if ( print_errors )
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '-W %s' requires an " )
                                       _T( "argument\n" )
                                     , argv[0]
                                     , pfound->name );
                        }
                        d->__nextchar += _tcslen( d->__nextchar );
                        return optstring[0] == _T(':') ? _T(':') : _T('?');
                    }
                }
                else
                {
                    d->optarg = NULL;
                }
                d->__nextchar += _tcslen( d->__nextchar );
                if ( longind != NULL )
                {
                    *longind = option_index;
                }
                if ( pfound->flag )
                {
                    *( pfound->flag ) = pfound->val;
                    return 0;
                }
                return pfound->val;
            }
            d->__nextchar = NULL;
            return _T( 'W' );
        }
        if ( temp[1] == _T( ':' ) )
        {
            if ( temp[2] == _T( ':' ) )
            {
                if ( *d->__nextchar != _T( '\0' ) )
                {
                    d->optarg = d->__nextchar;
                    d->optind++;
                }
                else
                {
                    d->optarg = NULL;
                }
                d->__nextchar = NULL;
            }
            else
            {
                if ( *d->__nextchar != _T( '\0' ) )
                {
                    d->optarg = d->__nextchar;
                    d->optind++;
                }
                else if ( d->optind == argc )
                {
                    if ( print_errors )
                    {
                        _ftprintf( stderr
                                 , _T( "%s: option requires an " )
                                   _T( "argument -- '%c'\n" )
                                 , argv[0]
                                 , c );
                    }
                    d->optopt = c;
                    if ( optstring[0] == _T( ':' ) )
                    {
                        c = _T( ':' );
                    }
                    else
                    {
                        c = _T( '?' );
                    }
                }
                else
                {
                    d->optarg = argv[d->optind++];
                }
                d->__nextchar = NULL;
            }
        }
        return c;
    }
}
 
int _getopt_internal( int argc
                    , TCHAR *const * argv
                    , const TCHAR* optstring
                    , const struct option* longopts
                    , int* longind
                    , int long_only
                    , int posixly_correct )
{
    int result;
    getopt_data.optind = optind;
    getopt_data.opterr = opterr;
    result = _getopt_internal_r( argc
                               , argv
                               , optstring
                               , longopts
                               , longind
                               , long_only
                               , &getopt_data
                               , posixly_correct );
    optind = getopt_data.optind;
    optarg = getopt_data.optarg;
    optopt = getopt_data.optopt;
    return result;
}


int getopt( int argc, TCHAR *const * argv, const TCHAR* optstring) _GETOPT_THROW
{
    return _getopt_internal( argc
                           , argv
                           , optstring
                           , ( const struct option * ) 0
                           , ( int * ) 0
                           , 0
                           , 0 );
}


int getopt_long( int argc
               , TCHAR *const * argv
               , const TCHAR* options
               , const struct option* long_options
               , int* opt_index ) _GETOPT_THROW
{
    return _getopt_internal( argc
                           , argv
                           , options
                           , long_options
                           , opt_index
                           , 0
                           , 0 );
}
 
int _getopt_long_r( int argc
                  , TCHAR *const * argv
                  , const TCHAR* options
                  , const struct option* long_options
                  , int* opt_index
                  , struct _getopt_data* d )
{
    return _getopt_internal_r( argc
                             , argv
                             , options
                             , long_options
                             , opt_index
                             , 0
                             , d
                             , 0 );
}
 
int getopt_long_only( int argc
                    , TCHAR *const * argv
                    , const TCHAR* options
                    , const struct option* long_options
                    , int* opt_index ) _GETOPT_THROW
{
    return _getopt_internal( argc
                           , argv
                           , options
                           , long_options
                           , opt_index
                           , 1
                           , 0 );
}
 
int _getopt_long_only_r( int argc
                       , TCHAR *const * argv
                       , const TCHAR* options
                       , const struct option* long_options
                       , int* opt_index
                       , struct _getopt_data* d )
{
    return _getopt_internal_r( argc
                             , argv
                             , options
                             , long_options
                             , opt_index
                             , 1
                             , d
                             , 0 );
}
 
void getopt_reset() _GETOPT_THROW
{
    optarg  = NULL;
    optind  = 1;
    opterr  = 1;
    optopt  = _T( '?' );
    //
    getopt_data.optind            = 0;
    getopt_data.opterr            = 0;
    getopt_data.optopt            = 0;
    getopt_data.optarg            = NULL;
    getopt_data.__initialized     = 0;
    getopt_data.__nextchar        = NULL;
    getopt_data.__ordering        = 0;
    getopt_data.__posixly_correct = 0;
    getopt_data.__first_nonopt    = 0;
    getopt_data.__last_nonopt     = 0;
}


getopt库源代码以及编译方法可参考:CMake实战

标签:__,option,int,C++,optind,参数,argv,getopt,解析
From: https://www.cnblogs.com/ncepubye/p/17808950.html

相关文章

  • 全网最详细4W字Flink全面解析与实践(上)
    本文已收录至GitHub,推荐阅读......
  • spring boot aop 中获取requestbody参数
    packagecom.xkcoding.log.aop.aspectj;importjava.io.BufferedReader;importjava.io.IOException;importjava.util.Map;importjava.util.Objects;importjavax.servlet.http.HttpServletRequest;importorg.aspectj.lang.JoinPoint;importorg.aspectj.lang.Pr......
  • JavaScript 函数、函数构造、函数调用、参数、函数返回值、变量的作用域、预解析
    一、函数及函数的构造函数是一个可重用的代码块,用来完成某个特定功能。每当需要反复执行一段代码时,可以利用函数来避免重复书写相同代码。函数包含着的代码只能在函数被调用时才会执行,就可以避免页面载入时执行该脚本简单来说就是一个封装,封装的是一个特定的功能,重复使用函......
  • c/c++ 指针的江湖传说
    万物皆内存,内存有两个东西:地址、值。普通变量、引用变量、指针变量,二级指针变量,数组,指针数组...等等,皆内存。【指针】intx=10;//变量int*pX=&x;//指针变量int**ppX=&pX;//二级指针变量//地址,值std::cout<<&x<<","<<x<<std::endl;s......
  • c++入门基础
    c++打算法竞赛的优点是,输入输出比较方便,里面封装的stl库可以直接用,例如sort排序,直接一行代码就行了,时间复杂度也很友好。整数:输入:输出:小数:输入:输出:数组:输入:输出:字符串:输入:输出:结构体:输入输出:模板:点击查看代码#include<bits/stdc++.h>usingnames......
  • 数据库问题解析
    1、表连接表连接(JOIN)是在多个表中间通过⼀定的连接条件,使表之间发⽣关联进⽽能从多个表之间获取数据。2、3、表联合union:对两个结果集进⾏并集操作,不包括重复⾏unionall:对两个结果集进⾏并集操作,包括重复⾏注意事项:①每条SELECT语句必须拥有相同数量的列;②每条SELE......
  • 浅析C++中浮点数在内存中的存储方式
    1.任何数据在内存中都是以二进制的形式进行存储。例如,short型数据1156,由于在32位机和64位机都占2B一共16位其二进制形式为:0000010010000100。在IntelCPU架构的系统中(目前用的最多的硬件架构系统),存放方式为10000100(低地址单元)00000100(高地址单元),因为IntelCPU的......
  • 梳理C++各种数据类型所占字节数和表示范围
    Outline1.数据类型所在字节数与程序运行平台有关2.列举各种数据类型所占字节数1.数据类型所在字节数与程序运行平台有关不同的平台上对不同数据类型分配的字节数是不同的。平台环境的理解:硬件架构操作系统(OS)编译器(Compiler)程序的运行环境取决于上述配件。原因:64位机......
  • 使用C++实现Range序列生成器
    在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间......
  • 使用C++实现Range序列生成器
    在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间,......