实验资料
- 网易云课程地址:实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 网易云课堂昵称:Natsukashiii
- 学号:SA17225129
- 我的github地址
实验要求
- 用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
- 链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
- 可以将通用的Linktable模块集成到我们的menu程序中;
实验内容
- 在实验文件夹下创建lab4文件夹,在lab4文件夹中进行此次试验;
- 在lab4文件夹中创建linktable.c 、linktable.h、menu.c 三个文件;
- 在linktable.h中对这个接口需要实现的方法进行定义,linktable.c中则为上述头文件中预定义的具体实现,在menu.c中定义主要执行的main函数等;
- 使用gcc编译menu.c文件并执行编译后的文件;
- 最后进行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
实验总结
实现了用可重用的链表模块,提高了程序的可重用性和拓展性。