因工作需要写一个console工具程序,运行参数很多,记得linux下有一个系统函数getopt可以很好得帮助程序员解析命令行参数,但是在VC中没有这个函数,研究了下linux中对该函数的帮助信息和头文件getopt.h,重新实现了getopt和getopt_long这两个函数,因为没有读过linux下getopt这个函数的源代码,所以这个函数肯定不够完善,不过经过试用,还是能够满足我个人需求的,这里把源代码贴出来,也请熟悉或者读过getopt源代码的朋友指正。 GetOpt.h
/******************************************************************************
*
* Filename: GetOpt.h
*
* Description: 命令行参数解析器
*
* Date: 2008-06-19
*
* Author: 常海龙 (Email:[email protected])
*
* Copyright (c) 2008 常海龙
*
*******************************************************************************/
#ifdef __cplusplus
extern"C" {
#endif
extern int optind; //再次再次调用 getopt() 时的下一个 argv 指针的索引
extern int optopt; //最后一个已知选项
extern char* optarg; //指向当前选项参数(如果有)的指针
extern int getopt( int argc, char *const argv[], const char *shortopts);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
extern"C" {
#endif
struct option
{
char *name; //指向长选项名称的指针
int has_arg; //表示选项是否有参数
int *flag;
int val; //表示选项的短参数
};
extern int getopt_long (int argc, char *const argv[],
const char *shortopts, const struct option *longopts,
int *longind);
#ifdef __cplusplus
}
#endif
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#define CASE_SENSITIVE //定义参数处理器是否大小写敏感
GetOpt.c
/******************************************************************************
*
* Filename: GetOpt.c
*
* Description: 命令行参数解析器
*
* Date: 2008-06-19
*
* Author: 常海龙 (Email:[email protected])
*
* Copyright (c) 2008 常海龙
*
*******************************************************************************/
#include"GetOpt.h"
#include"string.h"
int optind = 1; //即将进行扫描的参数在argv[]中的索引
//存放解析后返回值如果某一个argument无效,返回'?',该值存放argument
int optopt;
char* optarg; //如果当前参数有后续参数,该值指向这个后续参数
///////////////////////////////////////////////////////////////////////////////
int paser_shotops(int argc,char *const argv[],
size_t length, //欲解析的argument项的长度
char *item_cont, //存放欲解析的argument
const char *shortopts
)
{
char *pos = NULL;
if(length == 2 && item_cont[0] == '-') //如果符合 -h 这样的条件就可进行解析
{
pos = strchr(shortopts,item_cont[1]); //当前argument在shortopts中出现的起始位置
if(NULL == pos)
{
optind++; //如果在shortopts中找不到,则返回'?'
optopt = item_cont[1];
return '?';
}
else
{
if(*(++pos) == ':') //如果该项带有后续参数,用optarg存储
optarg = argv[++optind];
optind++;
return item_cont[1];
}
}
else //如果不符合解析的条件,返回'?'
{
optopt = item_cont[0];
optind = argc;
return '?';
}
}
///////////////////////////////////////////////////////////////////////////////
int paser_longopts(int argc, char *const argv[],
size_t length, //欲解析的argument项的长度
char *item_cont, //存放欲解析的argument
const char *shortopts,
const struct option *longopts
)
{
char *assist_arg = NULL; //辅助字符串
int long_index = 0; //longopts的索引
//如果欲解析的argument长度大于2,并且第一,二个字符都是'-'
if( (length > 2) && (item_cont[0] == '-') && (item_cont[1] == '-'))
{
//循环longopts,查找和当前参数匹配的项目
while(longopts[long_index].name != NULL)
{
if(strcmp(item_cont+2,longopts[long_index].name) == 0)
{
if(longopts[long_index].has_arg == required_argument)
optarg = argv[++optind];
if(longopts[long_index].has_arg == optional_argument)
{
//因为是可选后续参数,首先取得后续参数,然后判断
assist_arg = argv[optind + 1];
if(assist_arg[0] != '-')
{
optarg = assist_arg;
++optind;
}
}
//在longopts中找到匹配项后,返回val值
optopt = longopts[long_index].val;
optind++;
return optopt;
}
else
long_index++;
}
//如果在longopts中没有匹配项,则进行提示并继续解析后面的参数
optopt = item_cont[2];
++optind;
return '?';
}
else
//对短参数项进行解析
return paser_shotops(argc,argv,length,item_cont,shortopts);
}
///////////////////////////////////////////////////////////////////////////////
int getopt( int argc, char *const argv[], const char *shortopts )
{
char *arg_item = NULL;
size_t len = 0;
if(argc == 1)
return -1;
else
{
for(; optind < argc; optind++)
{
arg_item = argv[optind];
len = strlen(arg_item);
#ifndef CASE_SENSITIVE
arg_item = strlwr(arg_item);
#endif
return paser_shotops(argc,argv,len,arg_item,shortopts);
}
optind = 1; //如果解析完毕,在最后将optind重置为1
return -1;
}
}
///////////////////////////////////////////////////////////////////////////////
int getopt_long (int argc, char *const argv[],
const char *shortopts, const struct option *longopts,
int *longind)
{
char *pos = NULL;
char *arg_item = NULL;
size_t len = 0;
if(argc == 1)
return -1;
else
{
for(; optind < argc; optind++)
{
arg_item = argv[optind];
len = strlen(arg_item);
#ifndef CASE_SENSITIVE
arg_item = strlwr(arg_item);
#endif
//在与解析的参数项后面加0,方便字符串的操作
*(arg_item+len) = 0;
return paser_longopts(argc,argv,len,arg_item,shortopts,longopts);
}
optind = 1; //如果解析完毕,在最后将optind重置为1
return -1;
}
}
///////////////////////////////////////////////////////////////////////////////