闲云控制台(一)控制台命令解析框架

来源:互联网 发布:美国读金融硕士知乎 编辑:程序博客网 时间:2024/04/28 06:42

发布闲云控制台连载系列,会不定期加入新功能~

先发一个命令解析的框架

/*********************************************************************闲云万能控制台***************************************    作者: 闲云野鹤*********     QQ: 836663997*********    QQ群: 116920287  欢迎加入*********    邮箱: xianyun1230@163.com*********    博客: blog.csdn.net/xianyun2009******************  功能会一直更新!***************************************************/#define _CRT_SECURE_NO_WARNINGS//vs中关闭安全开发周期(SDL)检测#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <memory.h>#include <conio.h>/***定义控制台的支持能力***/#define MAX_CMD100//支持命令的最大数目#define LEN_CMD50//命令中名称的最大的长度#define LEN_ARGU50//命令中参数的最大的长度#define LEN_OBJ900//命令中命令对象的最大的长度#define LEN_SUMMARY100//命令简介长度/***用于处理区返回执行状态***/#define OVER_CMD5//命令名称太长#define OVER_ARGU6//命令参数太长#define OVER_OBJ7//命令对象太长/***用于执行区命令返回执行状态***/#define NO0//执行失败#define OK1//执行成功#define ERR_NOCMD2//命令错误#define ERR_ARGU3//参数错误#define ERR_NOOBJ4//对象错误typedef struct //输入命令的结构{char Cmd_Name[LEN_CMD + 1];//命令名称char Cmd_Arguments[LEN_ARGU + 1];//参数列表char Cmd_Object[LEN_OBJ + 1];//命令对象}Command, *pCommand;typedef int (*CMD_FUN)(pCommand);typedef struct //命令结构,存放支持的命令{char Cmd_Name[LEN_CMD];//命令名称CMD_FUN _Fun;//处理函数char Cmd_Summary[LEN_SUMMARY];}CMD_ITEM, *pCMD_ITEM;CMD_ITEM KEEP_CMD[MAX_CMD] = { 0 };//用于存放注册命令unsigned int CUR_CMD_NUM = 0;//当前已注册命令数目/**************************************处理命令***************************      进行转换和分发命令****************************************************//***转换命令***/int Translate_Command(char* _cmd_str, pCommand _cmd){memset(_cmd, 0, sizeof(Command));//_cmd全部置0while ('\0' != *_cmd_str && isspace(*_cmd_str))//清除命令两端空格类字符++_cmd_str;int _len = strlen(_cmd_str) - 1;while (_len >= 0 && isspace(*(_cmd_str + _len)))*(_cmd_str + _len--) = '\0';//分割命令char* p_str = strchr(_cmd_str, ' ');if (!p_str){if (_len + 1 > LEN_CMD)//命令名称太长return OVER_CMD;strcpy(_cmd->Cmd_Name, _cmd_str);//分离命令名称}else{if (p_str - _cmd_str > LEN_CMD)//命令名称太长return OVER_CMD;strncpy(_cmd->Cmd_Name, _cmd_str, p_str - _cmd_str);//分离命令名称while ('\0' != *p_str && isspace(*p_str))++p_str;if ('-' == *p_str)//检测参数标识'-'{++p_str;char* p_space = strchr(p_str, ' ');if (p_space){if (p_space - p_str > LEN_ARGU)//命令参数太长return OVER_ARGU;strncpy(_cmd->Cmd_Arguments, p_str, p_space - p_str);//分离参数while ('\0' != p_space && isspace(*p_space))++p_space;if (strlen(p_space) > LEN_OBJ)//命令对象太长return OVER_OBJ;strcpy(_cmd->Cmd_Object, p_space);//分离命令对象}else{if (strlen(p_str) > LEN_ARGU)//命令参数太长return OVER_ARGU;strcpy(_cmd->Cmd_Arguments, p_str);//分离参数}}else{if (strlen(p_str) > LEN_OBJ)//命令对象太长return OVER_OBJ;strcpy(_cmd->Cmd_Object, p_str);//分离命令对象}}return OK;}/***检验命令是否已注册并返回指针***/const pCMD_ITEM Loc_Command(pCommand _cmd){unsigned int i;for (i = 0; i < CUR_CMD_NUM; ++i){if (0 == strcmp(_cmd->Cmd_Name, KEEP_CMD[i].Cmd_Name))return &KEEP_CMD[i];}return NULL; //无此命令}/***分发命令***/int Dispatch_Command(pCommand _cmd){//printf("Dispatch command:%s<-\targu:%s<-\tobj:%s<-\n", _cmd->Cmd_Name, _cmd->Cmd_Arguments, _cmd->Cmd_Object);const pCMD_ITEM ploc = Loc_Command(_cmd);if (NULL == ploc)return ERR_NOCMD;return ploc->_Fun(_cmd);}/*******************************************命令处理区      命令的执行区,对每个命令进行各自的处理  ****需不断添加功能****  每个函数格式都应为 int NAME(pCommand ); NAME为函数名  注意:!每个函数都应返回一个执行状态,状态详细  内容见上方'执行区命令返回状态'!****************************************/int Hello(pCommand b){printf("\t\t欢迎来到闲云万能控制台!\n\t   Welcome to xianyun Super Console!\n");return OK;}int Help(pCommand b){Hello(b);printf("\n");printf("    命令\t\t简介\n");int i;for (i = 0; i < CUR_CMD_NUM; i++){printf("    %s\t\t%s\n", KEEP_CMD[i].Cmd_Name, KEEP_CMD[i].Cmd_Summary);}printf("\n    命令格式: 命令名称 [-参数] [对象]  例如:help -arv hello  参数和对象可省略\n");printf("    注意参数中每个字符都算作一个一个参数,即例子中有三个参数a、r、v\n");return OK;}/*************************************************注册区每个命令都应在这里注册********************每个在命令处理区定义的命令都应仿照   _register_one_cmd("命令名称", 映射函数名称, "功能简介");   格式在下面注册,否则将无法识别注意: 命令名称大小写敏感!***********************************************/void _register_one_cmd(char* _cmd_name, CMD_FUN _fun, char* _cmd_summary);void Register_Cmd(){_register_one_cmd("hello", Hello, "显示欢迎信息");_register_one_cmd("help", Help, "显示帮助信息");}void _register_one_cmd(char* _cmd_name, CMD_FUN _fun, char* _cmd_summary){strcpy(KEEP_CMD[CUR_CMD_NUM].Cmd_Name, _cmd_name);strcpy(KEEP_CMD[CUR_CMD_NUM].Cmd_Summary, _cmd_summary);KEEP_CMD[CUR_CMD_NUM]._Fun = _fun;++CUR_CMD_NUM;}/*************************************************信息提示区用于各种错误、返回值的处理和交互***********************************************/void ResultVal_Deal(int re){switch (re){case OK:return;case NO:printf("命令未能成功执行,请检测您的指令是否正确!\n");return;case ERR_NOCMD:printf("命令无法识别!\n");return;case ERR_ARGU:printf("命令参数错误!\n");return;case ERR_NOOBJ:printf("命令对象错误!\n");return;case OVER_CMD:printf("命令名称太长!\n");return;case OVER_ARGU:printf("命令参数太长!\n");return;case OVER_OBJ:printf("命令对象太长!\n");return;}}int main(){char cmd_str[1024];int result = 0;Command _cmd;Register_Cmd();Help(&_cmd);while (1){printf(">");gets(cmd_str);result = Translate_Command(cmd_str, &_cmd);ResultVal_Deal(result);if (OK == result){result = Dispatch_Command(&_cmd);ResultVal_Deal(result);}}return 0;}


0 0