实验报告_ASE_lab4

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

实验要求:

  • 用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
  • 链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
  • 可以将通用的Linktable模块集成到我们的menu程序中;
  • 接口规范;

实验步骤

心得体会:

此次实验的特点是利用通用的链表结点结构体(tLinkTableNode),构建相应的应用链表节点(tLinkNode), tLinkTableNode 是 tLinkNode 中的一个成员,需要注意的一点是,想要实现链表重用,必须在定义 tLinkNode 时把 tLinkTableNode 放在第一个成员的位置,否则会发生指针错误。

源代码:

menu.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "linktable.h"


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

typedef struct DataNode
{
    tLinkTableNode *pNext;
    char* cmd;
    char* desc;
    int(*handler)();
} tDataNode;

int Help();
int Quit();

tDataNode * FindCmd(tLinkTable *linkTable, char * cmd)
{
    if (linkTable == NULL)
    {
        return NULL;
    }

    tDataNode * pNode = (tDataNode *)GetLinkTableHead(linkTable);
    //printf("***  %s  ***", pNode->desc);
    while (pNode != NULL)
    {
        if (strcmp(pNode->cmd, cmd) == 0)
        {
            return pNode;
        }
        pNode = (tDataNode *)GetNextLinkTableNode(linkTable, (tLinkTableNode *)pNode);
    }
    return NULL;
}

int ShowAllCmd(tLinkTable* linktable)
{
    tDataNode *pNode = (tDataNode*)GetLinkTableHead(linktable);
    while (pNode != NULL)
    {
        printf("%s-%s\n", pNode->cmd, pNode->desc);
        pNode = (tDataNode*)GetNextLinkTableNode(linktable, (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 Program V1.3";
    pNode->handler = NULL;
    AddLinkTableNode(*ppLinkTable, (tLinkTableNode *)pNode);

    pNode = (tDataNode *)malloc(sizeof(tDataNode));
    pNode->cmd = "quit";
    pNode->desc = "Quit from Menu Program V1.3";
    pNode->handler = Quit;
    AddLinkTableNode(*ppLinkTable, (tLinkTableNode *)pNode);

    return 0;
}

tLinkTable *linktable = NULL;

int main()
{
    InitMenuData(&linktable);
    //tDataNode * q = (tDataNode *)GetLinkTableHead(linktable);
    //printf("%s", q->desc);
    while (1)
    {
        char cmd[CMD_MAX_LEN];
        printf("Input a cmd number > ");
        //scanf_s("%s", cmd,_countof(cmd));
        scanf("%s", cmd);
        tDataNode *p = FindCmd(linktable, cmd);
        if (p == NULL)
        {
            printf("This is a wrong cmd!\n");
            continue;
        }
        printf("%s - %s\n", p->cmd, p->desc);
        if (p->handler != NULL)
        {
            p->handler();
        }
    }
}

int Help()
{
    ShowAllCmd(linktable);
    return 0;
}

int Quit()
{
    exit(0);
}

linktable.c

#include "linktable.h"
#include <stdlib.h>
#include<stdio.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 AddLinkTableNode(tLinkTable * pLinkTable, tLinkTableNode * pNode)
{
    if (pLinkTable->SumOfNode == 0)
    {
        pLinkTable->pHead = pNode;
        pLinkTable->pTail = pNode;
        pLinkTable->SumOfNode++;
        pNode->pNext = NULL;
        return 0;
    }
    pLinkTable->pTail->pNext = pNode;
    pLinkTable->pTail = pNode;
    pNode->pNext = NULL;
    pLinkTable->SumOfNode++;
    return 0;
}

int DelLinkTableNode(tLinkTable * pLinkTable, tLinkTableNode * pNode)
{
    if (pLinkTable->SumOfNode == 0)
    {
        printf("LinkTable is NULL");
        exit(0);
    }
    tLinkTableNode *q = pLinkTable->pHead;
    if (q == pNode)
    {
        pLinkTable->pHead = pLinkTable->pHead->pNext;
        free(pNode);
        return 0;
    }
    while (q->pNext != pNode)
    {
        q = q->pNext;
    }
    tLinkTableNode *r = q->pNext;
    q->pNext = r->pNext;
    free(r);
    return 0;
}

tLinkTableNode * GetLinkTableHead(tLinkTable *LinkTable)
{
    return LinkTable->pHead;
}

tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode)
{
    return pNode->pNext;
}

linktable.h

#ifndef LINK_TABLE_H
#define LINK_TABLE_H

#include <pthread.h>

#define SUCCESS 0
#define FAILURE (-1)



//LinkTable Node Type
typedef struct LinkTableNode
{
    struct LinkTableNode * pNext;
}tLinkTableNode;

//LinkTable Type
typedef struct LinkTable
{
    tLinkTableNode *pHead;
    tLinkTableNode *pTail;
    int SumOfNode;
    pthread_mutex_t mutex;
}tLinkTable;

//Create a LinkTable
 tLinkTable * CreateLinkTable();

//Delete a LinkTable
int DeleteLinkTable(tLinkTable *pLinkTable);

//Add a LinkTableNode to LinkTable
int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode);

//Delete a LinkTableNode from LinkTable
int DelLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode);

//Get LinkTableHead
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);

//Get next LinkTableNode
tLinkTableNode * NextLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode * pNode);

#endif /* _LINK_TABLE_H_ */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值