C++参数解析参数
《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实战