SA17225400【哪来的妖精 + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006 】
实验要求
- 用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
- 链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
- 可以将通用的Linktable模块集成到我们的menu程序中;
- 接口规范;
实验过程
创建lab4
在目录中创建文件并编写代码
linktable.h
#ifndef _LINK_TABLE_H_ #define _LINK_TABLE_H_ #include <pthread.h> #define SUCCESS 0 #define FAILURE (-1) typedef struct LinkTableNode { struct LinkTableNode *pNext; }tLinkTableNode; typedef struct LinkTable { tLinkTableNode *pHead; tLinkTableNode *pTail; int SumOfNode; pthread_mutex_t mutex; }tLinkTable; tLinkTable *CreateLinkTable(); int DeleteLinkTable(tLinkTable *pLinkTable); int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode); int DelLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode); tLinkTableNode *GetLinkTableHead(tLinkTable *pLinkTable); tLinkTableNode *GetLinkTableNextNode(tLinkTable *pLinkTable,tLinkTableNode *pNode); #endif
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 -> pHead = NULL; pLinkTable -> pTail = NULL; pLinkTable -> SumOfNode = 0; return pLinkTable; } int DeleteLinkTable(tLinkTable *pLinkTable) { if (pLinkTable == NULL) return FAILURE; while (pLinkTable -> pHead != NULL) { tLinkTableNode *p = pLinkTable -> pHead; pLinkTable -> pHead = pLinkTable -> pHead -> pNext; pLinkTable -> SumOfNode--; free(p); } pLinkTable -> pHead = NULL; pLinkTable -> pTail = NULL; free(pLinkTable); return SUCCESS; } int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode) { if (pLinkTable == NULL || pNode == NULL) return FAILURE; pNode ->pNext = NULL; if (pLinkTable -> pHead == NULL) pLinkTable -> pHead = pNode; if (pLinkTable -> pTail == NULL) pLinkTable -> pTail = pNode; else { pLinkTable -> pTail -> pNext = pNode; pLinkTable -> pTail = pNode; } pLinkTable -> SumOfNode++; return SUCCESS; } int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode) { if(pLinkTable == NULL || pNode == NULL) return FAILURE; if(pLinkTable->pHead == pNode) { pLinkTable->pHead = pLinkTable->pHead->pNext; pLinkTable->SumOfNode--; if(pLinkTable->SumOfNode == 0) pLinkTable->pTail = NULL; return SUCCESS; } tLinkTableNode * pTempNode = pLinkTable->pHead; while(pTempNode != NULL) { if(pTempNode->pNext == pNode) { pTempNode->pNext = pTempNode->pNext->pNext; pLinkTable->SumOfNode--; if(pLinkTable->SumOfNode == 0) pLinkTable->pTail = NULL; return SUCCESS; } pTempNode = pTempNode->pNext; } return FAILURE; } tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable) { if(pLinkTable == NULL) { return NULL; } return pLinkTable->pHead; } tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode) { if(pLinkTable == NULL || pNode == NULL) return NULL; tLinkTableNode * pTempNode = pLinkTable->pHead; while(pTempNode != NULL) { if(pTempNode == pNode) return pTempNode->pNext; pTempNode = pTempNode->pNext; } return NULL; }
menu.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "linktable.h" #define CMD_MAX_LEN 128 typedef struct DataNode { tLinkTableNode *pNext; char *cmd; char *desc; int (*handler)(); }tDataNode; int Help(); int Date(); int Route(); int Exit(); tDataNode *FindCmd(tLinkTable *head, char *cmd) { tDataNode *pNode = (tDataNode*)GetLinkTableHead(head); while (pNode != NULL) { if (strcmp(pNode -> cmd, cmd) == 0) { 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 ", 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 = "Menu List: "; pNode->handler = Help; AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode); pNode = (tDataNode*)malloc(sizeof(tDataNode)); pNode->cmd = "version"; pNode->desc = "Menu Programe V1.0 "; pNode->handler = NULL; AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode); pNode = (tDataNode*)malloc(sizeof(tDataNode)); pNode->cmd = "date"; pNode->desc = "Print the date "; pNode->handler = Date; AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode); pNode = (tDataNode*)malloc(sizeof(tDataNode)); pNode->cmd = "route"; pNode->desc = "Print the route table "; pNode->handler = Route; AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode); pNode = (tDataNode*)malloc(sizeof(tDataNode)); pNode->cmd = "exit"; pNode->desc = "The Programe will exit "; pNode->handler = Exit; AddLinkTableNode(*ppLinkTable,(tLinkTableNode *)pNode); return 0; } tLinkTable *head = NULL; int main() { char cmd[CMD_MAX_LEN]; InitMenuData(&head); while(1) { printf(" Please input your cmd: "); scanf("%s",cmd); tDataNode *p = FindCmd(head,cmd); if(p == NULL) { printf("This is a wrong cmd! "); continue; } printf("%s - %s ", p->cmd, p->desc); if(p->handler != NULL) { p->handler(); } } return 0; } int Help() { ShowAllCmd(head); return 0; } int Date() { system("date"); return 0; }; int Route() { system("route"); return 0; }; int Exit() { exit(0); return 0; };
运行截图
上传到GitHUb:
实验小结
这次实验内容较多,中间出现了一点曲折,调了很久终于成功运行了。通过这次学习学到了很多东西。