实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
来源:互联网 发布:java书籍推荐 豆瓣 编辑:程序博客网 时间:2024/06/05 16:00
一、实验要求
- 给lab5-1.tar.gz找bug,quit命令无法运行的bug
- 利用callback函数参数使Linktable的查询接口更加通用
- 注意接口的信息隐藏
二、实验过程
- 本次实验中所用版本库地址为:https://github.com/WhiteWhiteW/se_2017.git
- 使用mkdir命令创建lab5目录,并在该目录下对lab5-1.tar.gz进行解压缩,使用到的命令是
tar -zxvf lab5-1.tar.gz
- 使用Xcode进行编译调试debug
项目导入后,运行结果如下所示。可以看到输入命令为quit时,得到的返回结果是
This is a wrong cmd!
,并非预期中的结果。修改linktable.c中的
while(pNode != pLinkTable -> pTail)改为while(pNode != NULL)
原因:在linktable.c中的
tLinkTableNode * SearchLinkTableNode
下,由于quit是最后一个节点,当找到quit时循环条件不满足而退出,不会执行函数体中的代码,因此无法执行quit命令。所以将while(pNode != pLinkTable -> pTail)
改为while(pNode != NULL)
。利用callback函数参数使linktable的查询接口更加通用,注重接口的信息隐藏。
代码如下。
linktable.h
/********************************************************************//* FILE NAME : linktabe.h *//* PRINCIPAL AUTHOR : Wyy *//* SUBSYSTEM NAME : LinkTable *//* MODULE NAME : LinkTable *//* LANGUAGE : C *//* TARGET ENVIRONMENT : ANY *//* DATE OF FIRST RELEASE : 2017/10/22 *//* DESCRIPTION : interface of Link Table *//********************************************************************/#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);/* * Search a LinkTableNode from LinkTable * int Conditon(tLinkTableNode * pNode); */tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode));/* * get LinkTableHead */tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);/* * get next LinkTableNode */tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode);#endif /* _LINK_TABLE_H_ */
linktable.c
/********************************************************************//* FILE NAME : linktabe.c *//* PRINCIPAL AUTHOR : Wyy *//* SUBSYSTEM NAME : LinkTable *//* MODULE NAME : LinkTable *//* LANGUAGE : C *//* TARGET ENVIRONMENT : ANY *//* DATE OF FIRST RELEASE : 2017/10/22 *//* DESCRIPTION : interface of Link Table *//********************************************************************/#include<stdio.h>#include<stdlib.h>#include"linktable.h"/* * Create a LinkTable */tLinkTable * CreateLinkTable(){ tLinkTable * pLinkTable = (tLinkTable* )malloc(sizeof(tLinkTable)); if(pLinkTable == NULL) { return NULL; } pLinkTable->pHead = NULL; pLinkTable->pTail = NULL; pLinkTable->SumOfNode = 0; pthread_mutex_init(&(pLinkTable->mutex), NULL); return pLinkTable;}/* * Delete a LinkTable */int DeleteLinkTable(tLinkTable *pLinkTable){ if(pLinkTable == NULL) { return FAILURE; } while(pLinkTable->pHead != NULL) { tLinkTableNode * p = pLinkTable->pHead; pthread_mutex_lock(&(pLinkTable->mutex)); pLinkTable->pHead = pLinkTable->pHead->pNext; pLinkTable->SumOfNode -= 1 ; pthread_mutex_unlock(&(pLinkTable->mutex)); free(p); } pLinkTable->pHead = NULL; pLinkTable->pTail = NULL; pLinkTable->SumOfNode = 0; pthread_mutex_destroy(&(pLinkTable->mutex)); free(pLinkTable); return SUCCESS;}/* * Add a LinkTableNode to LinkTable */int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode){ if(pLinkTable == NULL || pNode == NULL) { return FAILURE; } pNode->pNext = NULL; pthread_mutex_lock(&(pLinkTable->mutex)); if(pLinkTable->pHead == NULL) { pLinkTable->pHead = pNode; } if(pLinkTable->pTail == NULL) { pLinkTable->pTail = pNode; } else { pLinkTable->pTail->pNext = pNode; pLinkTable->pTail = pNode; } pLinkTable->SumOfNode += 1 ; pthread_mutex_unlock(&(pLinkTable->mutex)); return SUCCESS;}/* * Delete a LinkTableNode from LinkTable */int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode){ if(pLinkTable == NULL || pNode == NULL) { return FAILURE; } pthread_mutex_lock(&(pLinkTable->mutex)); if(pLinkTable->pHead == pNode) { pLinkTable->pHead = pLinkTable->pHead->pNext; pLinkTable->SumOfNode -= 1 ; if(pLinkTable->SumOfNode == 0) { pLinkTable->pTail = NULL; } pthread_mutex_unlock(&(pLinkTable->mutex)); return SUCCESS; } tLinkTableNode * pTempNode = pLinkTable->pHead; while(pTempNode != NULL) { if(pTempNode->pNext == pNode) { pTempNode->pNext = pTempNode->pNext->pNext; pLinkTable->SumOfNode -= 1 ; if(pLinkTable->SumOfNode == 0) { pLinkTable->pTail = NULL; } pthread_mutex_unlock(&(pLinkTable->mutex)); return SUCCESS; } pTempNode = pTempNode->pNext; } pthread_mutex_unlock(&(pLinkTable->mutex)); return FAILURE;}/* * Search a LinkTableNode from LinkTable * int Conditon(tLinkTableNode * pNode); */tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode)){ if(pLinkTable == NULL || Conditon == NULL) { return NULL; } tLinkTableNode * pNode = pLinkTable->pHead; while(pNode != NULL) { if(Conditon(pNode) == SUCCESS) { return pNode; } pNode = pNode->pNext; } return NULL;}/* * get LinkTableHead */tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable){ if(pLinkTable == NULL) { return NULL; } return pLinkTable->pHead;}/* * get next LinkTableNode */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
/********************************************************************//* FILE NAME : menu.c *//* PRINCIPAL AUTHOR : Wyy *//* SUBSYSTEM NAME : menu *//* MODULE NAME : menu *//* LANGUAGE : C *//* TARGET ENVIRONMENT : ANY *//* DATE OF FIRST RELEASE : 2017/10/22 *//* DESCRIPTION : This is a menu program *//********************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "linktable.h"int Help();int Quit();#define CMD_MAX_LEN 128#define DESC_LEN 1024#define CMD_NUM 10char cmd[CMD_MAX_LEN];/* data struct and its operations */typedef struct DataNode{ tLinkTableNode * pNext; char* cmd; char* desc; int (*handler)();} tDataNode;int SearchCondition(tLinkTableNode * pLinkTableNode){ tDataNode * pNode = (tDataNode *)pLinkTableNode; if(strcmp(pNode->cmd, cmd) == 0) { return SUCCESS; } return FAILURE; }/* find a cmd in the linklist and return the datanode pointer */tDataNode* FindCmd(tLinkTable * head, char * cmd){ return (tDataNode*)SearchLinkTableNode(head,SearchCondition);}/* show all cmd in listlist */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;}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.0"; pNode->handler = NULL; AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode); pNode = (tDataNode*)malloc(sizeof(tDataNode)); pNode->cmd = "quit"; pNode->desc = "Quit from Menu Program V1.0"; pNode->handler = Quit; AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode); return 0; }/* menu program */tLinkTable * head = NULL;int main(){ InitMenuData(&head); /* cmd line begins */ while(1) { printf("Input a cmd number > "); scanf("%s", cmd); tDataNode *p = FindCmd(head, 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(head); return 0; }int Quit(){ exit(0);}
三、实验结果
修改之后,得到运行结果如下所示。可看到,输入命令为quit时,会退出当前正在执行的程序,并得到预期的输出结果
Quit from Menu Program V1.0
.在命令行下使用
gcc menu.c linktable.c -o menu
命令进行编译,并且使用./menu
命令运行结果。
可得到结果如下。- help命令可得到命令提示菜单列表
- version命令可得到当前程序版本信息
- quit命令退出当前程序
- 其他输入默认为错误的输入信息
四、提交到github
五、心得体会
在上次的实验四中也遇到了类似的问题,上次出现的问题是段错误,经仔细查证,最后发现出现问题的地方在于链表节点的存储部分。
在本次实验中,熟悉了callback函数的使用,对模块化的编程思想有了进一步的学习。debug在实际代码调试中起到很重要的作业,自己还需继续努力。
阅读全文
0 0
- 实验五.用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验报告五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 实验报告五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 软件工程(C编码实践篇)”实验报告 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- “软件工程(C编码实践篇)”实验报告【实验五:用callback增强链表模块来实现命令行菜单小程序V2.8】
- [高级软件工程实验]用callback增强链表模块来实现命令行菜单小程序V2.8
- 软件工程(C编码实践篇) 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 用callback增强链表模块来实现命令行菜单小程序V2.8
- 用callback增强链表模块来实现命令行菜单小程序V2.8
- Oracle常用sql语句
- 使用Easy-UI 和SSH JPA 按条件查询分页
- java基础(八)——内部类
- C++ STL之vector用法总结
- 构造函数与普通函数的区别
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- 手慢无 | 年薪30万也离职学的Linux运维课?到底教什么?
- 怎样成为知乎大V?爬取张佳玮138w+知乎关注者:数据可视化
- 一图看尽Linux发行版:最全Linux发行版进化编年史
- String类总结之内存分析
- NYIST-2017大一新生第二次周赛题解
- TCP协议中的序列号
- ThreadLocal学习
- 倍增源代码