您的位置:首页 > 移动开发 > 微信开发

用可重用的链表模块来实现命令行菜单小程序V2.5

2017-10-15 19:52 513 查看
【网易云课堂昵称:JaYiFen + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006 】

实验要求:

用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;

链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;

可以将通用的Linktable模块集成到我们的menu程序中;

接口规范;

实验思路:

将上一节的代码进行改造重用,将每个功能封装成一个链表节点。然后在menu中调用等操作。实现更进一步的模块化设计。

实验代码(因为代码较多就不截图上传,直接提出源代码):

1.menu.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linktable.h"
int help();
int quit();

#define CMD_MAX_LEN 128
#define DESC_LEN 1024
#define CMD_NUM 10

typedef struct DataNode
{
tLinkTableNode *pNext;
char* cmd;
char* desc;
int(*handler)();
struct DataNode *next;
}tDataNode;
用可重用的链表模块来实现命令行菜单小程序V2.5
tDataNode *FindCmd(tLinkTable *head, char *cmd)
{
tDataNode* pNode=(tDataNode*)GetLinkTableHead(head);
while(NULL != pNode)
{
if(!strcmp(pNode->cmd,cmd))
{
return pNode;
}
pNode=(tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode*)pNode);
}
return NULL;
}

int ShowAllCmd(tLinkTable* head)
{
tDataNode *pNode=(tDataNode*)GetLinkTableHead(head);
while(pNode !=NULL)
{
printf("%s - %s\n",pNode->cmd,pNode->desc);
pNode = (tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode*)pNode);
}
return 0;
}

int InitMenuData(tLinkTable ** ppLinkTable)
{
*ppLinkTable=CreateLinkTable();
tDataNode* pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="help";
pNode->desc="help command:";
pNode->handler=help;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="version";
pNode->desc="menu program v1.1 beta";
pNode->handler=NULL;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd="quit";
pNode->desc="quit this software";
pNode->handler=quit;
AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode);
return 0;
}

tLinkTable* head=NULL;

int main()
{
InitMenuData(&head);
while(1)
{
char cmd[CMD_MAX_LEN];
printf("Please Input Command >");
scanf("%s",cmd);
tDataNode *p = FindCmd(head,cmd);
if(NULL == p)
{
printf("wrong cmd!\n");
continue;
}
printf("%s - %s\n",p->cmd,p->desc);
if(NULL != p -> handler)
{
p -> handler();
}
}
}

int help()
{
printf("Menu List:\n");
ShowAllCmd(head);
return 0;
}

int quit()
{
exit(0);
return 0;
}


2.linktable.h
#ifndef _LINK_TABLE_H_
#define _LINK_TABLE_H_

#define SUCCESS 0
#define FAILURE (-1)

typedef struct LinkTableNode
{
struct LinkTableNode *pNext;
}tLinkTableNode;

typedef struct LinkTable
{
tLinkTableNode *pHead;
tLinkTableNode *pTail;
int SumOfNode;
}tLinkTable;

tLinkTable *CreateLinkTable();
int DeleteLinkTable(tLinkTable *pLinkTable);
int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode);
int DeleteLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode);
tLinkTableNode *GetLinkTableHead(tLinkTable *pLinkTable);
tLinkTableNode *GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode);

#endif

3.linktable.c
#include <stdio.h>
#include <stdlib.h>
#include "linktable.h"

tLinkTable *CreateLinkTable()
{
tLinkTable *pLinkTable=(tLinkTable*)malloc(sizeof(tLinkTable));
pLinkTable->pHead=NULL;
pLinkTable->SumOfNode=0;
return pLinkTable;
}

int DeleteLInkTable(tLinkTable *pLinkTable)
{
if(NULL == pLinkTable)
{
return FAILURE;
}
if(NULL == pLinkTable->pHead)
{
free(pLinkTable);
return SUCCESS;
}
tLinkTableNode *pNode=GetLinkTableHead(pLinkTable);
tLinkTableNode *pTempNode;

while(NULL != pNode)
{
pTempNode=pNode;
pNode=GetNextLinkTableNode(pLinkTable,pNode);
free(pTempNode);
}
free(pNode);
return SUCCESS;
}

int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode)
{
if(NULL == pLinkTable || NULL == pNode)
{
return FAILURE;
}
if(pLinkTable->pHead == NULL)
{
pLinkTable->pHead=pNode;
return SUCCESS;
}
tLinkTableNode *ptrNode=GetLinkTableHead(pLinkTable);
while(ptrNode->pNext != NULL)
{
ptrNode=ptrNode->pNext;
}
ptrNode->pNext=pNode;
return SUCCESS;
}

int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode)
{
if(pLinkTable == NULL || pNode == NULL)
{
return FAILURE;
}
if(pLinkTable->pHead == NULL)
{
free(pLinkTable->pHead);
return SUCCESS;
}
tLinkTableNode *ptrNode = GetLinkTableHead(pLinkTable);
while(ptrNode->pNext != pNode)
{
ptrNode=ptrNode->pNext;
}
tLinkTableNode *ptrTemp=ptrNode->pNext;
ptrNode->pNext=ptrTemp->pNext;
free(ptrTemp);
return SUCCESS;

}

tLinkTableNode *GetLinkTableHead(tLinkTable *pLinkTable)
{
if(pLinkTable == NULL || pLinkTable->pHead == NULL)
{
return NULL;
}
tLinkTableNode *pNode=pLinkTable->pHead;
return pNode;
}

tLinkTableNode *GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode)
{
if(pLinkTable == NULL || pLinkTable->pHead == NULL)
{
return NULL;
}
return pNode->pNext;
}


实验运行截图:



上传代码:



GitHub地址

实验总结:

从实验和视频课中可以知道接口的分类:

1.共享数据或变量名;

2.call-in functions;

3.同步调用接口;

4,异步调用接口;

用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;

链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;

可以将通用的Linktable模块集成到我们的menu程序中;

接口规范;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐