自定义的命令行处理程序 --DEMO版
设计思路:将命令行参数全部添加到链表,在链表中处理相关的命令
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <direct.h>
#define BUFF_MAX 512
typedef enum __CMDLIST{
CMD_NULL = -1,
CMD_00,
CMD_01,
CMD_02,
CMD_03,
CMD_04,
CMD_05,
CMD_06,
CMD_07,
CMD_08,
CMD_09,
CMD_10,
CMD_11,
CMD_12,
CMD_13,
CMD_14,
CMD_15,
CMD_16,
CMD_17,
CMD_18,
CMD_19,
CMD_20,
CMD_21,
CMD_22,
CMD_23,
CMD_24,
CMD_25,
CMD_26,
CMD_27,
CMD_28,
CMD_29,
CMD_30,
CMD_31,
CMD_32,
CMD_33,
CMD_34,
CMD_35,
CMD_36,
CMD_37,
CMD_38,
CMD_39,
CMD_40,
CMD_41,
CMD_42,
CMD_43,
CMD_44,
CMD_45,
CMD_46,
CMD_47,
CMD_48,
CMD_49,
CMD_50,
CMD_51,
CMD_52,
CMD_53,
CMD_54,
CMD_55,
CMD_56,
CMD_57,
CMD_58,
CMD_59,
CMD_60,
CMD_61,
CMD_62,
CMD_63,
CMD_64,
CMD_65,
CMD_66,
CMD_67,
CMD_68,
CMD_69,
CMD_70,
CMD_71,
CMD_72,
CMD_73,
CMD_74,
CMD_75,
CMD_76,
CMD_77,
CMD_78,
CMD_79,
CMD_80,
CMD_81,
CMD_82,
CMD_83,
CMD_84,
CMD_85,
CMD_86,
CMD_87,
CMD_88,
CMD_89,
CMD_90,
CMD_91,
CMD_92,
CMD_93,
CMD_94,
CMD_95,
CMD_96,
CMD_97,
CMD_98,
CMD_99,
CMD_MAX,
}CMDLIST;
typedef int (*CMDFUN)(int argc,char* argv[]);
typedef struct __DATA{
CMDLIST CommandIndex; //命令编号
char name[BUFF_MAX]; //命令名称
char data[BUFF_MAX]; // 命令参数
}DataType ;
typedef struct __LIST{
int index;
struct __DATA listdata;
struct __LIST* prev;
struct __LIST* next;
}LIST;
//初始化一个链表
static LIST* ListInit(void)
{
LIST *head = NULL,*end = NULL;
head = (LIST*)malloc(sizeof(LIST));
end = (LIST*)malloc(sizeof(LIST));
if(head == NULL || end == NULL)
{
printf("list init error\n");
return NULL;
}
head->index = 1;
head->listdata.CommandIndex = CMD_NULL;
sprintf(head->listdata.name,"head");
sprintf(head->listdata.data,"NULL");
head->prev = NULL;
head->next = end;
end->index = head->index + 1;
end->listdata.CommandIndex = CMD_MAX;
sprintf(end->listdata.name,"end");
sprintf(end->listdata.data,"NULL");
end->prev = head;
end->next = NULL;
return head;
}
//获取链表的总节点数
static int ListGetNodeNum(LIST* list)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
while(head->next != NULL)
{
head = head->next;
}
return head->index;
}
//获取index节点的数据
static LIST* ListGetNode(LIST* list,int index)
{
LIST* head = list;
LIST* ret = NULL;
if(head == NULL)
{
printf("list head error\n");
return NULL;
}
if(index > ListGetNodeNum(head))
{
return NULL;
}
while(head->index != index)
{
head = head->next;
}
return head;
}
//申请新节点
static LIST* ListCreateNode(DataType data)
{
LIST *node = (LIST*)malloc(sizeof(LIST));
if(node == NULL)
{
return NULL;
}
node->index = 0;
node->listdata.CommandIndex = data.CommandIndex;
strcpy(node->listdata.name,data.name);
strcpy(node->listdata.data,data.data);
node->prev = NULL;
node->next = NULL;
return node;
}
//在末尾添加一个节点
static int ListAdd(LIST* list,DataType data)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
while(head->next != NULL)
{
head = head->next;
}
LIST* node = ListCreateNode(data);
if(node == NULL)
{
printf("list CreateNode error\n");
return -1;
}
LIST* prev = head->prev;
prev->next = node;
node->prev = prev;
node->next = head;
head->prev = node;
node->index = prev->index + 1;
head->index = node->index + 1;
return 0;
}
static int ListAdd(LIST* list,CMDLIST cmd,const char* name,const char* data)
{
DataType temp;
temp.CommandIndex = cmd;
strcpy(temp.name,name);
strcpy(temp.data,data);
return ListAdd(list,temp);
}
//在index位置添加一个节点
static int ListAdd(LIST* list,int index,DataType data)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
if(index > ListGetNodeNum(head))
{
return -1;
}
while(head->index != index)
{
head = head->next;
}
LIST* node = ListCreateNode(data);
if(node == NULL)
{
printf("list CreateNode error\n");
return -1;
}
LIST* prev = head->prev;
prev->next = node;
node->prev = prev;
node->next = head;
head->prev = node;
node->index = prev->index + 1;
while(head->next != NULL)
{
head->index ++;
head = head->next;
}
head->index ++;
return 0;
}
static int ListAdd(LIST* list,int index,CMDLIST cmd,const char* name,const char* data)
{
DataType temp;
temp.CommandIndex = cmd;
strcpy(temp.name,name);
strcpy(temp.data,data);
return ListAdd(list,index,temp);
}
//删除节点号为index的节点
static int ListDelet(LIST* list,int index)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
if(index > ListGetNodeNum(head))
{
return -1;
}
while(head->index != index)
{
head = head->next;
}
if(index == 1 ||head->next == NULL)
{
return 0;
}
LIST *prev = head->prev;
LIST *next = head->next;
prev->next = next;
next->prev = prev;
free(head);
head = NULL;
while(next->next != NULL)
{
next->index --;
next = next->next;
}
next->index --;
return 0;
}
//删除节点命令为cmdindex的节点
static int ListDelet(LIST* list,CMDLIST cmdindex)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
while(head->next != NULL)
{
if(head->listdata.CommandIndex == cmdindex &&head->index != 1)
{
LIST *prev = head->prev;
LIST *next = head->next;
prev->next = next;
next->prev = prev;
free(head);
head = next;
}
else
{
head = head->next;
}
}
head = list->next;
while(head->next != NULL)
{
head->index = head->prev->index + 1;
head = head->next;
}
head->index = head->prev->index + 1;
return 0;
}
//销毁一个链表
static int ListDestory(LIST* list)
{
LIST* head = list;
LIST* temp;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
int nodenum = ListGetNodeNum(head);
while(nodenum --)
{
temp = head->next;
free(head);
head = temp;
}
return 0;
}
//打印一个链表
static int ListPrintf(LIST* list)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
int nodenum = ListGetNodeNum(head);
while(nodenum --)
{
std::cout << "head->index:" << head->index << std::endl;
std::cout << "head->listdata.CommandIndex:" << head->listdata.CommandIndex << std::endl;
std::cout << "head->listdata.name :" << head->listdata.name << std::endl;
std::cout << "head->listdata.data :" << head->listdata.data << std::endl;
head = head->next;
}
return 0;
}
//打印index节点的数据
static int ListPrintf(LIST* list,int index)
{
LIST* head = list;
if(head == NULL)
{
printf("list head error\n");
return -1;
}
LIST* temp = ListGetNode(head,index);
if(temp == NULL)
{
return -1;
}
std::cout << "index:" << temp->index << std::endl;
std::cout << "listdata.CommandIndex:" << temp->listdata.CommandIndex << std::endl;
std::cout << "listdata.name :" << temp->listdata.name << std::endl;
std::cout << "listdata.data :" << temp->listdata.data << std::endl;
return 0;
}
//修改index节点的数据
static int ListAlterDataType(LIST* list,int index,DataType data)
{
LIST* head = list;
if(head == NULL)
{
return -1;
}
LIST* temp = ListGetNode(head,index);
if(temp == NULL)
{
return -1;
}
memcpy(&temp->listdata,&data,sizeof(DataType));
return 0;
}
//修改index节点的数据
static int ListAlterDataType(LIST* list,int index,CMDLIST cmd,const char* name,const char* data)
{
LIST* head = list;
if(head == NULL)
{
return -1;
}
LIST* temp = ListGetNode(head,index);
if(temp == NULL)
{
return -1;
}
if(cmd != CMD_NULL)
temp->listdata.CommandIndex = cmd;
if(name)
strcpy(temp->listdata.name,name);
if(data)
strcpy(temp->listdata.data,data);
return 0;
}
typedef int (*cmdfun)(LIST*,int);
typedef struct __COMMAND{
CMDLIST cmd;
const char* name;
const char* explain;
cmdfun fun;
}CMD;
int CMDHELP(LIST*,int);
int CMDVER(LIST*,int);
int CMDDIR(LIST*,int);
int CMDJPG(LIST*,int);
static const CMD cmdlist[] =
{
{CMD_00,"--help","Displays command line help options",CMDHELP},
{CMD_01,"--ver" ,"Display version number",CMDVER},
{CMD_02,"--dir","Add the files in this directory",CMDDIR},
{CMD_03,"--jpg","Handle JPG/JPEG format file, users do not use!",CMDJPG},
{CMD_04,"--bmp","Handle BMP format file, users do not use!",NULL},
{CMD_05,"--avi","Handle AVI format file, users do not use!",NULL},
};
static const unsigned int cmdlength = sizeof(cmdlist)/sizeof(CMD);
static int ListTranslateCmd(LIST* list,int index)
{
int ret = 0;
const char* str = ListGetNode(list,index)->listdata.data;
if(strstr(str,".jpg") != NULL){
ListAlterDataType(list,index,CMD_NULL,"--jpg",NULL);
}else if(strstr(str,".bmp") != NULL){
ListAlterDataType(list,index,CMD_NULL,"--bmp",NULL);
}else if(strstr(str,".avi") != NULL){
ListAlterDataType(list,index,CMD_NULL,"--avi",NULL);
}else if(strstr(str,".jpeg") != NULL){
ListAlterDataType(list,index,CMD_NULL,"--jpg",NULL);
}else{
}
return ret;
}
static int ListTranslateCmd(LIST* list,const char* name)
{
int ret = 0;
if(strstr(name,".jpg") != NULL){
ListAdd(list,CMD_03,"--jpg",name);
}else if(strstr(name,".bmp") != NULL){
ListAdd(list,CMD_04,"--bmp",name);
}else if(strstr(name,".avi") != NULL){
ListAdd(list,CMD_05,"--avi",name);
}else if(strstr(name,".jpeg") != NULL){
ListAdd(list,CMD_03,"--jpg",name);
}else{
}
return ret;
}
static int ListCommandRegister(LIST* list,const CMD* cmd)
{
signed int listlength = ListGetNodeNum(list);
if(listlength < 0)
{
printf("%s\n",__FUNCTION__);
return -1;
}
for(int i = 0;i<listlength;i++)
{
ListTranslateCmd(list,i + 1);
}
for(int i = 0;i<listlength;i++)
{
for (int j = 0; j < cmdlength; j++)
{
if (strcmp(ListGetNode(list,i + 1)->listdata.name,cmd[j].name) == 0)
{
ListAlterDataType(list,i + 1,cmd[j].cmd,NULL,NULL);
}
}
}
ListDelet(list,CMD_NULL);
return 0;
}
static int ListCommandExecute(LIST* list,const CMD* cmd)
{
if (list == NULL)
{
return -1;
}
signed int listlength = ListGetNodeNum(list);
if(listlength < 0)
{
printf("%s\n",__FUNCTION__);
return -1;
}
for(int i = 0;i<listlength;i++)
{
signed int cmdindex = ListGetNode(list,i+1)->listdata.CommandIndex;
if(cmdindex == CMD_NULL || cmdindex == CMD_MAX)
{
continue;
}
if(cmd[cmdindex].fun)
cmd[cmdindex].fun(list,i + 1);
}
return 0;
}
//这里优先处理一下命令,如--dir 将目录下面的文件添加至链表
static int ListCommandTranslate(LIST* list,const CMD* cmd)
{
if (list == NULL)
{
return -1;
}
signed int listlength = ListGetNodeNum(list);
if(listlength < 0)
{
printf("%s\n",__FUNCTION__);
return -1;
}
for(int i = 0;i<listlength;i++)
{
signed int cmdindex = ListGetNode(list,i+1)->listdata.CommandIndex;
if(cmdindex == CMD_NULL || cmdindex == CMD_MAX)
{
continue;
}
switch (cmdindex)
{
case CMD_02:
break;
default:
continue;
break;
}
if(cmd[cmdindex].fun)
cmd[cmdindex].fun(list,i + 1);
}
return 0;
}
int main(int argc,char* argv[])
{
LIST* list = ListInit();
for (int i = 1; i < argc; i++)
{
ListAdd(list,CMD_NULL,argv[i],argv[i]);
}
ListCommandRegister(list,cmdlist);
ListCommandTranslate(list,cmdlist);
ListCommandExecute(list,cmdlist);
//ListPrintf(list);
ListDestory(list);
list = NULL;
return 0;
}
int CMDHELP(LIST* list,int index)
{
std::cout << "Command line help options:" << std::endl;
for (unsigned int i = 0; i < cmdlength; i++)
{
std::cout << cmdlist[i].name << ":" << cmdlist[i].explain << std::endl;
}
}
int CMDVER(LIST* list,int index)
{
std::cout << "Ver:" << __DATE__ <<"/"<< __TIME__<< std::endl;
}
int CMDDIR(LIST* list,int index)
{
#define BUFFMAX 1024
char buffer[BUFFMAX];
getcwd(buffer,BUFF_MAX);
strcat(buffer,"\\");
//处理文件目录时,优先使用脚本的方法,使用windows API可能会造成错误
system("dir /b /s /a-d > allfiles.txt");
FILE *fp = fopen("allfiles.txt","r");
if(fp == NULL)
{
return -1;
}
unsigned int FileSize = 0;
fseek(fp,0,SEEK_END);
FileSize = ftell(fp);
fseek(fp,0,SEEK_SET);
char linebuff[BUFF_MAX];
while (FileSize != ftell(fp))
{
fgets(linebuff,BUFF_MAX,fp);
if(strstr(linebuff,buffer) != NULL)
{
char* buff = linebuff;
buff += strlen(buffer);
buff[strlen(buff)-1] = '\0';
ListTranslateCmd(list,buff);
}
}
fclose(fp);
fp = NULL;
ListDelet(list,index);
system("del allfiles.txt");
}
int CMDJPG(LIST* list,int index)
{
if(list == NULL)
{
return -1;
}
//防止用户输入--jpg 命令
if (strcmp(ListGetNode(list,index)->listdata.data,"--jpg") == 0)
{
return -1;
}
}