一个命令行参数解析器

    因工作需要写一个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:hailongchang@163.com) 

*

*                             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:hailongchang@163.com) 

*

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

    }

}



///
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值