一、实验要求
1.用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
2.链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
3.可以将通用的Linktable模块集成到我们的menu程序中;
4.接口规范。
先贴出本文的gitbub地址:https://github.com/Ulov888/lab4
以及最终运行截图:
二、实验过程
在上周的基础上,本周添加了新的任务,使用可重用的链表模块来实现命令行程序,那么就从这个链表模块写起吧,分别创建linktable.c和linktable.h文件
linktable.c
#include <stdio.h>
#include <stdlib.h>
#include "linktable.h"
tLinkTable* CreateLinkTable()
{
tLinkTable* pLinkTable=(tLinkTable*)malloc(sizeof(tLinkTable));
if(pLinkTable == NULL)
{
return NULL;
}
pLinkTable->Head=NULL;
pLinkTable->Tail=NULL;
pLinkTable->num=0;
return pLinkTable;
}
int DelLinkTable(tLinkTable* pLinkTable)
{
if(pLinkTable ==NULL)
{
return FAILURE;
}
while(pLinkTable->Head != NULL)
{
tLinkNode* pNode = pLinkTable->Head;
pLinkTable->Head = pLinkTable->Head->Next;
free(pNode);
pLinkTable->num--;
}
pLinkTable->Head = NULL;
pLinkTable->Tail = NULL;
free(pLinkTable);
return SUCCESS;
}
int AddLinkNode(tLinkTable* pLinkTable, tLinkNode* pNode)
{
if(pLinkTable == NULL ||pNode == NULL)
{
return FAILURE;
}
pNode->Next = NULL;
if(pLinkTable->Head == NULL)
{
pLinkTable->Head = pNode;
}
if(pLinkTable->Tail == NULL)
{
pLinkTable->Tail = pNode;
}
else
{
pLinkTable->Tail->Next = pNode;
pLinkTable->Tail = pLinkTable->Tail->Next;
}
pLinkTable->num++;
return SUCCESS;
}
int DelLinkNode(tLinkTable* pLinkTable, tLinkNode* pNode)
{
if(pLinkTable ==NULL || pNode == NULL)
{
return FAILURE;
}
tLinkNode* p = pLinkTable->Head;
if(pLinkTable->Head == pNode)
{
pLinkTable->Head = pLinkTable->Head->Next;
free(p);
pLinkTable->num--;
}
if(pLinkTable->num ==0)
{
pLinkTable->Tail=NULL;
return SUCCESS;
}
while(p!= NULL)
{
if(p->Next == pNode)
{
tLinkNode* q = p->Next;
p->Next = p->Next->Next;
free(q);
pLinkTable->num--;
if(pLinkTable->num == 0)
{
pLinkTable->Tail = NULL;
}
return SUCCESS;
}
p = p->Next;
}
return FAILURE;
}
tLinkNode* GetHeadNode(tLinkTable* pLinkTable)
{
if(pLinkTable ==NULL||pLinkTable->Head==NULL)
{
return NULL;
}
return pLinkTable->Head;
}
tLinkNode* GetTailNode(tLinkTable* pLinkTable)
{
if(pLinkTable ==NULL||pLinkTable->Tail==NULL)
{
return NULL;
}
return pLinkTable->Tail;
}
tLinkNode* GetNextNode(tLinkTable* pLinkTable,tLinkNode *pNode)
{
if(pLinkTable==NULL||pNode==NULL)
{
return NULL;
}
tLinkNode* p=pLinkTable->Head;
while(p!=NULL)
{
if(p==pNode)
{
return p->Next;
}
p=p->Next;
}
return NULL;
}
linktable.h
#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
#define SUCCESS 0
#define FAILURE -1
typedef struct LinkNode
{
struct LinkNode *Next;
}tLinkNode;
typedef struct LinkTable
{
tLinkNode *Head;
tLinkNode *Tail;
int num;
}tLinkTable;
tLinkTable* CreatLinkTable();
int DelLinkTable(tLinkTable *pLinkTable);
int AddLinkNode(tLinkTable *pLinkTable,tLinkNode* pNode);
int DelLinkNode(tLinkTable *pLinkTable,tLinkNode* pNode);
tLinkNode* GetHeadNode(tLinkTable* pLinkTable);
tLinkNode* GetTailNode(tLinkTable* pLinkTable);
tLinkNode* GetNextNode(tLinkTable* pLinkTable,tLinkNode *pNode);
#endif
在上周的作业里,也要做如下修改:
对linklist.c
tDataNode * FindCmd(tLinkTable*head,char * cmd)
{
tDataNode* p=(tDataNode*)GetHeadNode(head);
while(p!=NULL)
{
if(strcmp(p->cmd,cmd)==0)
return p;
p=(tDataNode*)GetNextNode(head,(tLinkNode*)p);
}
return NULL;
}
int ShowAllCmd(tLinkTable* head)
{
tDataNode* p=(tDataNode*)GetHeadNode(head);
printf("Menu list:\n");
while(p!=NULL)
{
printf("%s-%s\n",p->cmd,p->desc);
p=(tDataNode*)GetNextNode(head,(tLinkNode*)p);
}
return 0;
}
接下来贴出main文件:
#include <string.h>
#include "linklist.h"
#include "linktable.h"
#define CMD_MAX_LEN 128
void mathDemo();
void dogBark();
void help();
void quit();
int Initmenu(tLinkTable ** pLinkTable);
tDataNode * FindCmd(tLinkTable * head,char *cmd);
int ShowAllCmd(tLinkTable* head);
tLinkTable* head=NULL;
int main()
{
char cmd[CMD_MAX_LEN];
Initmenu(&head);
printf("ATTENTION: input 'help' you can get all commands!\n");
while(1)
{
printf("please input a command-->");
scanf("%s",cmd);
tDataNode *p=FindCmd(head,cmd);
if(p==NULL)
{
printf("this is a wrong cmd!\n");
continue;
}
printf("command:%s description:%s\n",p->cmd,p->desc);
if(p->handler != NULL)
{
p->handler();
printf("==================================\n");
}
}
return 0;
}
int Initmenu(tLinkTable ** pLinkTable)
{
*pLinkTable=CreateLinkTable();
tDataNode* pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="help";
pNode->desc="this is help command";
pNode->handler=help;
AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="mathDemo";
pNode->desc="this is math command";
pNode->handler=mathDemo;
AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="quit";
pNode->desc="This is quit cmd";
pNode->handler=quit;
AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="dogBark";
pNode->desc="This is a dog";
pNode->handler=dogBark;
AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
return 0;
}
void mathDemo()
{
printf("1 + 2 = %d\n",1+2);
}
void dogBark()
{
printf("Ruff!,RUff!,Ruff....!\n");
}
void help()
{
ShowAllCmd(head);
}
void quit()
{
printf("are you sure ? Y/N\t");
char flag;
scanf("%s",&flag);
if(flag=='Y'||flag == 'y'){
exit(0);
}
else
{
return ;
}
}