一、实验要求
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 ; } }