软件工程(C编码实践篇) 第四次作业实验报告
来源:互联网 发布:linux 装网卡 编辑:程序博客网 时间:2024/05/18 08:02
网易云课堂昵称:sa17225159
《软件工程(C编码实践篇)》MOOC课程作业 http://mooc.study.163.com/course/USTC-1000002006
实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
实验要求
- 用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
- 链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
- 可以将通用的Linktable模块集成到我们的menu程序中;
接口规范;
实验过程
1.建立远程仓库,并下载到本地,远程仓库地址:https://github.com/libaoquan95/seClass_lab4.git
git clone https://github.com/libaoquan95/seClass_lab4.git
并进入版本库并创建 menu.c linktable.h linktable.c 文件
2 linktable.h
#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;}tLinkTable;tLinkTable * CreateLinkTable();int DelLinkTable(tLinkTable* pLinkTable);int AddLinkTable(tLinkTable* pLinkTable,tLinkTableNode *pNode);int AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode);int DelLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode);tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);tLinkTableNode * GetNextLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode);#endif
3 linktable.c
#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 AddLinkTableNode(tLinkTable *pLinkTable, tLinkTableNode *pNode){ if (pLinkTable == NULL || pNode == NULL) return FAILURE; if (pLinkTable->pHead == NULL) { pLinkTable->pHead = pNode; pLinkTable->pTail = pNode; pLinkTable->SumOfNode = 1; } else { pLinkTable->pTail->pNext = pNode; pLinkTable->pTail = pNode; 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;}
4 menu.c
/* * Copyright (C) libaoquan95@github.com, 2017-2018 * * File name : menu.c * Principal author : libaoquan95 * Subsystem name : menu * Module name : menu * Language : C * Date of first release : 2017/10/09 * Deacription : This is a menu program*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include "linktable.h"#define CMD_MAX_LEN 128#define DESC_LEN 1024#define CMD_NUM 10int PrintCommand();int PrintSystemTime();int PrintCurrentWorkingDirectory();int Add();int Sub();int Mul();int Div();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); printf("-------------------------------------------------------------------\n"); while(pNode != NULL) { printf("\t\t %s: \t\t %s\n", pNode->cmd, pNode->desc); pNode= (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)pNode); } printf("-------------------------------------------------------------------\n"); return 0;}/*static tDataNode menu[] ={ {(tLinkTableNode*)&menu[1], "help", "Print all command of menu", PrintCommand}, {(tLinkTableNode*)&menu[2], "time", "Show system time", PrintSystemTime}, {(tLinkTableNode*)&menu[3], "pwd", "Show current working directory", PrintCurrentWorkingDirectory}, {(tLinkTableNode*)&menu[4], "add", "Calculate the summarize of the two integer numbers", Add}, {(tLinkTableNode*)&menu[5], "sub", "Calculate the subtractions of the two integer numbers", Sub}, {(tLinkTableNode*)&menu[6], "mul", "Calculate the multiplication of the two integer numbers", Mul}, {(tLinkTableNode*)&menu[7], "div", "Calculate the division of the two integer numbers", Div}, {(tLinkTableNode*)NULL, "quit", "Exit menu program", Quit}};*/int InitMenuData(tLinkTable **ppLinkTable){ /**ppLinkTable = CreateLinkTable(); (*ppLinkTable)->pHead = (tLinkTableNode*)&menu[0]; (*ppLinkTable)->pTail = (tLinkTableNode*)&menu[7]; (*ppLinkTable)->SumOfNode = 8;*/ *ppLinkTable = CreateLinkTable(); tDataNode *pNode0 = (tDataNode*)malloc(sizeof(tDataNode)); pNode0->cmd = "help"; pNode0->desc = "Print all command of menu"; pNode0->handler = PrintCommand; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode0); tDataNode *pNode1 = (tDataNode*)malloc(sizeof(tDataNode)); pNode1->cmd = "time"; pNode1->desc = "Show system time"; pNode1->handler = PrintSystemTime; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode1); tDataNode *pNode2 = (tDataNode*)malloc(sizeof(tDataNode)); pNode2->cmd = "pwd"; pNode2->desc = "Show current working directory"; pNode2->handler = PrintCurrentWorkingDirectory; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode2); tDataNode *pNode3 = (tDataNode*)malloc(sizeof(tDataNode)); pNode3->cmd = "add"; pNode3->desc = "Calculate the summarize of the two integer numbers"; pNode3->handler = Add; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode3); tDataNode *pNode4 = (tDataNode*)malloc(sizeof(tDataNode)); pNode4->cmd = "sub"; pNode4->desc = "Calculate the subtractions of the two integer numbers"; pNode4->handler = Sub; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode4); tDataNode *pNode5 = (tDataNode*)malloc(sizeof(tDataNode)); pNode5->cmd = "mul"; pNode5->desc = "Calculate the multiplication of the two integer numbers"; pNode5->handler = Mul; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode5); tDataNode *pNode6 = (tDataNode*)malloc(sizeof(tDataNode)); pNode6->cmd = "div"; pNode6->desc = "Calculate the division of the two integer numbers"; pNode6->handler = Div; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode6); tDataNode *pNode7 = (tDataNode*)malloc(sizeof(tDataNode)); pNode7->cmd = "quit"; pNode7->desc = "Exit menu program"; pNode7->handler = Quit; AddLinkTableNode(*ppLinkTable, (tLinkTableNode*)pNode7);}tLinkTable *head = NULL;int main(){ InitMenuData(&head); while(1) { char cmd[CMD_MAX_LEN]; printf("$menu > "); scanf("%s", cmd); tDataNode *p = FindCmd(head, cmd); if(p == NULL) { printf("ERROR: This is not a command, you can input 'help' to find command\n"); continue; } if(p->handler != NULL) { p->handler(); } }}/** * print all command and it's information * @param none * @return none */int PrintCommand(){ ShowAllCmd(head); return 0;}/** * print current time * @param none * @return none */int PrintSystemTime(){ struct tm *ptr; time_t it; it = time(NULL); ptr = localtime(&it); printf("%4d年%02d月%02d日 %d:%d:%d\n", ptr->tm_year + 1900, ptr->tm_mon + 1, ptr->tm_mday, ptr->tm_hour, ptr->tm_min,ptr->tm_sec); return 0;}/** * print current working directory path * @param none * @return none */int PrintCurrentWorkingDirectory(){ char buf[256]; getcwd(buf, sizeof(buf)); printf("当前路径: %s\n", buf); return 0;}/** * calculate add of two interage numbers * @param none * @return calculate result */ int Add() { int num1 = 0, num2 = 0; printf("input number1:"); scanf("%d", &num1); printf("input number2:"); scanf("%d", &num2); printf("%d + %d = %d\n", num1, num2, num1 + num2); return 0; } /** * calculate sub of two interage numbers * @param none * @return calculate result */ int Sub() { int num1 = 0, num2 = 0; printf("input number1:"); scanf("%d", &num1); printf("input number2:"); scanf("%d", &num2); printf("%d - %d = %d\n", num1, num2, num1 - num2); return 0; } /** * calculate mul of two interage numbers * @param none * @return calculate result */ int Mul() { int num1 = 0, num2 = 0; printf("input number1:"); scanf("%d", &num1); printf("input number2:"); scanf("%d", &num2); printf("%d * %d = %d\n", num1, num2, num1 * num2); return 0; } /** * calculate div of two interage numbers * @param none * @return calculate result */ int Div() { int num1 = 0, num2 = 0; printf("input number1:"); scanf("%d", &num1); printf("input number2:"); scanf("%d", &num2); if(num2 != 0) { printf("%d / %d = %d\n", num1, num2, num1 / num2); } else { printf("ERROR: don't division 0\n"); } return 0; } /** * quit command * @param none * @return none */ int Quit() { exit(0); return 0; }
5.编译程序并运行
5.1 编译
gcc linktable.h linktable.c menu.c -o menu./menu
5.2 运行
help 命令
time 命令
pwd 命令
add 命令
sub 命令
mul 命令
div 命令
错误的命令
quit 命令
6.上传至远程版本库
实验总结
远程仓库地址:https://github.com/libaoquan95/seClass_lab4.git
通过这次菜单程序模块化设计使我学会了许多的软件工程思想,体会到了模块化的巨大作用
本次实验设计了一个通用的链表模块,在调用时指定了具体的数据类型,体现了高类聚低耦合的思想,接口更加规范,使我们的代码更具有通用性并且更容易管理。
在实验中体会到了函数接口规范对于可重用的重要性,以及代码设计规范的一些方法。在编译的过程中也学习了链接的相关知识,对gcc编译器有了进一步的理解.
阅读全文
0 0
- 软件工程(C编码实践篇) 第四次作业实验报告
- 软件工程(C编码实践篇) 第五次作业实验报告
- 软件工程(C编码实践篇) 第七次作业实验报告
- 软件工程(C编码实践篇) 第二次作业实验报告
- 软件工程(C编码实践篇) 第三次作业实验报告
- “软件工程(C编码实践篇)”实验报告【实验一:写一个hello world小程序】
- “软件工程(C编码实践篇)”实验报告【实验二:命令行菜单小程序V1.0】
- 软件工程(C编码实践篇)”实验报告 实验二:命令行菜单小程序V1.0
- C++第四次实验-作业报告(2,3,4)
- c++ 第四次实验--作业报告
- C++第四次实验-作业报告
- 软件工程(C编码实践篇)实验一
- 软件工程第四次作业
- 软件工程第四次作业
- 软件工程(C编码实践篇)”实验报告一:写一个hello world小程序
- 软件工程第四次实验
- “软件工程(C编码实践篇)”实验报告【实验三:内部模块化的命令行菜单小程序V2.0】
- 软件工程(C编码实践篇)”实验报告实验七:将menu设计为可重用的子系统
- HashMap和Hashtable的区别
- spring管理事物
- java生成二维码
- Java NIO编写Socket服务器的一个例子
- 如何在Eclipse配置Tomcat服务器
- 软件工程(C编码实践篇) 第四次作业实验报告
- 关于dao设计模式,父类对象实例化指向子类,xxxDao xxx = new xxxDaoImpl的理解
- spark的运行模式总结
- 白盒测试
- Oracle中的Union、Union All、Intersect、Minus
- Java项目经验——程序员成长的钥匙
- C#验证码公用类
- 【机器学习实战】第15章 大数据与MapReduce
- Ionic3学习笔记(五)动画之使用 animate.css