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

来源:互联网 发布:mac一定要配苹果鼠标吗 编辑:程序博客网 时间:2024/06/05 05:47

【shawn520 + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006 】
【代码仓库】https://github.com/shawn520/SE.git

实验要求

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

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

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

  4. 接口规范;

实验过程

进入实验目录

git clone https://github.com/shawn520/SE.gitmkdir lab4cd lab4vim menu.c

menu.c中添加如下代码

#include <stdio.h>#include <stdlib.h>#include <string.h>#include "linktable.h"#define     FILEPATH_MAX          80#define     CMD_MAX_LENGTH         128void help();        void quit();typedef struct DataNode{    tLinkTableNode *pNext;    char *cmd;    char *desc;    void (*handler)();}tDataNode;char cwdbuff[64] = {0};char cwdbuffsub[64] = {0};//declare a tLinkTabletLinkTable *head = NULL;//find the commandtDataNode *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;}//show the descint 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;}//initint InitMenuData(tLinkTable **ppLinktable){    *ppLinktable = CreateLinkTable();    tDataNode *pNode = (tDataNode *)malloc(sizeof(tDataNode));    pNode->cmd = "help";    pNode->desc = "This is help command.";    pNode->handler = help;    AddLinkTableNode(*ppLinktable, (tLinkTableNode *)pNode);    pNode = (tDataNode *)malloc(sizeof(tDataNode));    pNode->cmd = "quit";    pNode->desc = "quit the command line.";    pNode->handler = quit;    AddLinkTableNode(*ppLinktable, (tLinkTableNode *)pNode);    return 0;}int main (){    char getCommand[CMD_MAX_LENGTH];    InitMenuData(&head);    while(1)    {        printf("Please Input Command: ");        scanf("%s",getCommand);        tDataNode *p = FindCmd(head,getCommand);        if(p == NULL)        {            printf("error: Wrong Command!!\n");                }        else        {            p -> handler();        }    }    return 0;}//show commmand imformationvoid help(){    ShowAllCmd(head);}//exitvoid quit(){    exit(0);}

编辑linktable.h

#ifndef __LINK_TABLE_H__#define __LINK_TABLE_H__#include<pthread.h>#define SUCCESS 0#define FAILURE (-1)//LinkTable Node Typetypedef struct LinkTableNode{    struct LinkTableNode *pNext;}tLinkTableNode;//LinkTable Typetypedef struct LinkTable{    tLinkTableNode *pHead;    tLinkTableNode *pTail;    int SumOfNode;    pthread_mutex_t mutex;}tLinkTable;//Create a LinkTabletLinkTable *CreateLinkTable();//Delete LinkTableint DeleteLinkTable(tLinkTable *pLinkTable);//Add CMDint AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode);//Delete CMDint DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode);//Get LinkTableHeadtLinkTableNode *GetLinkTableHead(tLinkTable *pLinkTable);//Get nextLinkTableNodetLinkTableNode *GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode *pNode);#endif

编辑 linktable.c

#include <stdio.h>#include <stdlib.h>#include "linktable.h"#define SUCCESS 0#define FAILURE (-1)tLinkTable *CreateLinkTable(){    tLinkTable *pLinkTable = (tLinkTable *)malloc(sizeof(tLinkTable));    if (pLinkTable == NULL)    {        printf("malloc error!\n");        return NULL;    }    pLinkTable->pHead = NULL;    pLinkTable->pTail = NULL;    pLinkTable->SumOfNode = 0;    pthread_mutex_init(&(pLinkTable->mutex), NULL);    return pLinkTable;}int DeleteLinkTable(tLinkTable *pLinkTable){    if (pLinkTable == NULL)    {        return SUCCESS;    }    while (pLinkTable->pHead != NULL)    {        tLinkTableNode *pNode = pLinkTable->pHead;        pLinkTable->pHead = pNode->pNext;        free(pNode);    }    free(pLinkTable);    return SUCCESS;}int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode){    if (pLinkTable == NULL || pNode == NULL)    {        printf("AddLinkTableNode error!\n");        return FAILURE;    }    pNode->pNext = NULL;    if (pLinkTable->pHead == NULL)    {        pLinkTable->pHead = pNode;        pLinkTable->pTail = pNode;        pLinkTable->SumOfNode += 1;    }    else    {        pLinkTable->pTail->pNext = pNode;        pLinkTable->pTail = pNode;        pLinkTable->SumOfNode += 1;    }    return SUCCESS;}int DelLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode){    if (pLinkTable == NULL || pNode == NULL)    {        printf("DelLinkTableNode error!\n");        return FAILURE;    }    tLinkTableNode *pFront = pLinkTable->pHead;    if (pFront == NULL)    {        printf("pLinkTable is NULL!\n");        return FAILURE;    }    else if (pFront == pNode)    {        pLinkTable->pHead = pFront->pNext;        free(pFront);        return SUCCESS;    }    tLinkTableNode *pBack = pFront;    pFront = pFront->pNext;    while (pFront != NULL)    {        if (pFront == pNode)        {            pBack->pNext = pFront->pNext;            free(pFront);            return SUCCESS;        }        pFront = pFront->pNext;        pBack = pBack->pNext;    }    printf("not find error!\n");    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 *p = pLinkTable->pHead;    if (p == NULL)    {        return NULL;    }    while (p != NULL)    {        if (p == pNode)        {            return p->pNext;        }        p = p->pNext;    }    return NULL;}

编译得到可执行文件

gcc linktable.c menu.c -o menu

并测试menu程序的功能,如图所示
这里写图片描述

完成后提交到git

git add  linktable.c linktable.h menu.c git commit -m 'menu_v2.5'git push

这里写图片描述

实验心得及体会:

实验越来越难了。

通用Linktable模块的接口设计
将通用的Linktable模块集成到我们的menu程序中
定义接口 - “天王盖地虎,宝塔镇河妖”黑社会接头也设计接口的!

  • 接口规范
  • 内聚和耦合
  • 通用原则

通用链表模块的接口设计

模块化的好处:包容变化

将通用的LinkTable集成到我们的menu程序中

本地化外部接口(Localize input and output)

欢迎大家访问我的——

  • GitHub主页: https://github.com/shawn520/SE
  • CSDN博客: http://blog.csdn.net/liushawn520
  • 新浪微博 @奔跑中的Shawn
阅读全文
0 0
原创粉丝点击