“软件工程(C编码实践篇)”实验报告【实验四:用可重用的链表模块来实现命令行菜单小程序V2.5】

本文介绍了一个基于链表模块实现的命令行菜单小程序,该程序通过定义通用的链表接口来增强程序的可重用性和扩展性。菜单包括基本的数学运算如加减乘除等功能,并利用链表来组织命令及其描述。

实验资料

  1. 网易云课程地址:实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
  2. 网易云课堂昵称:Natsukashiii
  3. 学号:SA17225129
  4. 我的github地址

实验要求

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

实验内容

  1. 在实验文件夹下创建lab4文件夹,在lab4文件夹中进行此次试验;
  2. 在lab4文件夹中创建linktable.c 、linktable.h、menu.c 三个文件;
  3. 在linktable.h中对这个接口需要实现的方法进行定义,linktable.c中则为上述头文件中预定义的具体实现,在menu.c中定义主要执行的main函数等;
  4. 使用gcc编译menu.c文件并执行编译后的文件;
  5. 最后进行git add,git commit,git push命令提交修改至我的github仓库。

实验思路

main.c实现了一种新的链表结构体,C的灵活性使得可以新类型节点加入原链表中。链表模块中的通用接口设计使得命令行菜单小程序的功能保持不变。


实验过程

1.在实验文件夹下创建lab4文件夹,在lab4文件夹中进行此次试验,复制lab3中的menu.c文件;

这里写图片描述

2.并在lab4文件夹中创建linktable.c 、linktable.h文件;

这里写图片描述

3.在linktable.h中对这个接口需要实现的方法进行定义;

这里写图片描述

4.linktable.c中具体实现上述头文件中的预定义;

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

5.在menu.c中定义主要执行的main函数等;

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

6.使用gcc编译menu.c文件并执行编译后的文件;

这里写图片描述

7.最后进行git add,git commit,git push命令提交修改至我的github仓库。
这里写图片描述


实验代码

  • menu.c代码
//
//  Created by Natsukashii on 2017/9/21.
//  Copyright © 2017年 Natsukashii. All rights reserved.
//

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

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

int Help();
int Add();
int Sub();
int Multi();
int Divide();
int Time();
int Power();
int Quit();

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

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\n", pNode->cmd, pNode->desc);
        pNode= (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)pNode);
    }
    return 0;
}

static tDataNode menu[] =
        {
                {(tLinkTableNode*)&menu[1],"version", "menu program v2.5",NULL},
                {(tLinkTableNode*)&menu[2],"help", "this is help cmd!", Help},
                {(tLinkTableNode*)&menu[3],"add", "this is add cmd!", Add},
                {(tLinkTableNode*)&menu[4],"sub", "this is sub cmd!", Sub},
                {(tLinkTableNode*)&menu[5],"mul", "this is multi cmd!", Multi},
                {(tLinkTableNode*)&menu[6],"div", "this is divide cmd!", Divide},
                {(tLinkTableNode*)&menu[7],"pow", "this is power cmd!", Power},
                {(tLinkTableNode*)&menu[8],"time", "this is time cmd!", Time},
                {(tLinkTableNode*)NULL,"quit", "this is quit cmd", Quit}
        };

int InitMenuData(tLinkTable **ppLinkTable)
{
    *ppLinkTable = CreateLinkTable();
    (*ppLinkTable)->pHead = (tLinkTableNode*)&menu[0];
    (*ppLinkTable)->pTail = (tLinkTableNode*)&menu[8];
    (*ppLinkTable)->SumOfNode = 9;
}

tLinkTable *head = NULL;

int main()
{
    InitMenuData(&head);
    printf("Welcome!Use 'help' to get how to use this system.\n");
    while(1)
    {
        char cmd[CMD_MAX_LEN];
        printf("input a cmd >");
        scanf("%s", cmd);
        tDataNode *p = FindCmd(head, cmd);
        printf("%d\n", head->SumOfNode);
        if(p == NULL)
        {
            printf("Wrong cmd!Use 'help' to get how to use this system.\n");
            continue;
        }
        printf("%s ---- %s\n", p->cmd, p->desc);
        if(p->handler != NULL)
        {
            p->handler();
        }
    }
}

int Help()
{
    ShowAllCmd(head);
}

int Add()
{
    int a,b;
    printf("Please input two integer numbers:\n");
    printf("Use 'Blank' or 'Enter' to divide the two numbers.\n");
    scanf("%d %d", &a, &b);
    int c = a + b;
    printf("The result of add cmd is:\n");
    printf("%d+%d=%d\n", a,b,c);
    return 0;
}

int Sub()
{
    int a,b;
    printf("Please input two integer numbers:\n");
    printf("Use 'Blank' or 'Enter' to divide the two numbers.\n");
    scanf("%d %d", &a, &b);
    int c = a - b;
    printf("The result of sub cmd is:\n");
    printf("%d-%d=%d\n", a,b,c);
    return 0;
}

int Multi()
{
    int a,b;
    printf("Please input two integer numbers:\n");
    printf("Use 'Blank' or 'Enter' to divide the two numbers.\n");
    scanf("%d %d", &a, &b);
    int c = a * b;
    printf("The result of mul cmd is:\n");
    printf("%d*%d=%d\n", a,b,c);
    return 0;
}

int Divide()
{
    int a,b;
    printf("Please input two integer numbers:\n");
    printf("Use 'Blank' or 'Enter' to divide the two numbers.\n");
    scanf("%d %d", &a, &b);
    int c = a / b;
    printf("The result of div cmd is:\n");
    printf("%d/%d=%d\n", a,b,c);
    return 0;
}

int Power()
{
    double a,b;
    printf("Please input two double numbers:\n");
    printf("Use 'Blank' or 'Enter' to divide the two numbers.\n");
    scanf("%lf %lf", &a, &b);
    double c = pow(a, b);
    printf("The result of pow cmd is: \n");
    printf("%.6f^%.6f=%.6f\n", a,b,c);
    return 0;
}

int Time()
{
    time_t t = time(0);
    char temp[64];
    strftime(temp, sizeof(temp), "%Y/%m/%d %X %A", localtime(&t));
    puts(temp);
    return 0;
}

int Quit()
{
    exit(0);
}
  • linktable.c代码
//
//  Created by Natsukashii on 2017/9/21.
//  Copyright © 2017年 Natsukashii. All rights reserved.
//

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

tLinkTable * CreateLinkTable()
{
    tLinkTable *pLinkTable=(tLinkTable*)malloc(sizeof(tLinkTable));
    if (pLinkTable == NULL)
    {
        return NULL;
        printf("create linktable failure! ");
    }
    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    return pLinkTable;
}

int DelLinkTable(tLinkTable* pLinkTable)
{
    if(pLinkTable == NULL)
        return FAILURE;

    while(pLinkTable->pHead != NULL)
    {
        tLinkTableNode *p = pLinkTable->pHead;
        pLinkTable->pHead = p->pNext;
        free(p);
    }

    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    free(pLinkTable);
    return SUCCESS;
}

int AddLinkTable(tLinkTable* pLinkTable,tLinkTableNode *pNode)
{
    if(pLinkTable == NULL || pNode == NULL)
        return FAILURE;
    if(pLinkTable->pHead == NULL && pLinkTable->pTail == NULL)
    {
        pLinkTable->pHead = pNode;
        pLinkTable->pTail = pNode;
        pLinkTable->pTail = NULL;
        pLinkTable->SumOfNode = 1;
    }
    else
    {
        pLinkTable->pTail->pNext = pNode;
        pLinkTable->pTail = pNode;
        pLinkTable->pTail->pNext = NULL;
        pLinkTable->SumOfNode ++;
    }
    return SUCCESS;
}

int DelLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode)
{
    if (pLinkTable == NULL)
        return FAILURE;
    tLinkTableNode *pWork = pLinkTable->pHead;
    tLinkTableNode *pre = pWork;

    if (pLinkTable->pHead == pNode)
    {
        pLinkTable->pHead = pWork->pNext;
        free(pWork);
        return SUCCESS;
    }

    while (pWork != NULL)
    {
        if(pWork == pNode)
        {
            pre->pNext = pWork->pNext;
            free(pWork);
            return SUCCESS;
        }
        pre = pWork;
        pWork = pWork->pNext;
    }

    return FAILURE;
}

tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable)
{
    if (pLinkTable->pHead == NULL)
    {
        printf("LinkTable is empty\n");
        return NULL;
    }
    return pLinkTable->pHead;
}

tLinkTableNode * GetNextLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode)
{
    if (pLinkTable == NULL || pNode == NULL)
    {
        printf("LinkTable is empty\n");
        return NULL;
    }

    tLinkTableNode *pWork = pLinkTable->pHead;

    while(pWork != NULL)
    {
        if(pWork == pNode)
            return pWork->pNext;
        pWork = pWork->pNext;
    }

    return NULL;
}
  • linktable.h代码
//
//  Created by Natsukashii on 2017/9/21.
//  Copyright © 2017年 Natsukashii. All rights reserved.
//
#ifndef _LINK_TABLE_H_
#define _LINK_TABLE_H_
#include <pthread.h>
#define  SUCCESS 0
#define  FAILURE (-1)

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

/*
 * LinkTableNode Type
 */
typedef struct LinkTable
{
    tLinkTableNode * pHead;
    tLinkTableNode * pTail;
    int            SumOfNode;
    //pthread_mutex_t_mutex ;
}tLinkTable;

tLinkTable * CreateLinkTable();
int DelLinkTable(tLinkTable* pLinkTable);
int AddLinkTable(tLinkTable* pLinkTable,tLinkTableNode *pNode);
int DelLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode);
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);
tLinkTableNode * GetNextLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode);
#endif

实验总结

实现了用可重用的链表模块,提高了程序的可重用性和拓展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值