[高级软件工程实验]用可重用的链表模块来实现命令行菜单小程序V2.5
来源:互联网 发布:小米账号破解软件 编辑:程序博客网 时间:2024/06/08 00:56
版本库URL:https://github.com/swagnhen/Advanced-Software-Engineering-Exercise.git
实验要求
1)用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;
2)链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;
3)可以将通用的Linktable模块集成到我们的menu程序中;
4)接口规范;
实验内容
可重用链表实现包含于linkedlist.h与linkedlist.c中
shell中各命令功能的实现包含在cmdopt.h与cmdopt.c中
main函数包含于shelllet.c中
通过gcc编译时请使用命令
gcc linkedlist.c cmdopt.c shelllet.c -o shelllet
可重用链表设计
typedef struct Node{ struct Node *next;} Node;typedef struct LinkedList{ Node *head; /*指向链表头结点*/ Node *tail; /*指向链表尾节点*/ int len; /*记录链表长度*/} LinkedList;LinkedList *initLinkedList(); /*初始化整个链表*/int delLinkedList(LinkedList *l); /*删除整个链表*/int addNode(LinkedList *l, Node *n); /*向链表尾添加一个节点*/int delNode(LinkedList *l, Node *n); /*删除某一节点*/Node *getHeadNode(LinkedList *l); /*取链表头结点*/Node *getNextNode(LinkedList *l, Node *n); /*取节点n的下一个节点*/
功能指令链表节点设计
typedef struct CmdNode{ Node *next; char *cmd; /*该节点所对应指令*/ int (*handler)(); /*指令cmd所对应的功能函数*/} CmdNode;int initMenuData(LinkedList **l); /*初始化功能指令链表*/CmdNode *findCmd(LinkedList *head, char *cmd); /*根据cmd字段寻找某一功能指令节点*/
具体实现
linkedlist.c
#include <stdio.h>#include <stdlib.h>#include "linkedlist.h"LinkedList *initLinkedList(){ LinkedList *l = (LinkedList *)malloc(sizeof(LinkedList)); if (l == NULL) { return NULL; } l->head = NULL; l->tail = NULL; l->len = 0; return l;}int delLinkedList(LinkedList *l){ if (l == NULL) { return -1; } while (l->head != NULL) { Node *p = l->head; l->head = l->head->next; free(p); l->len--; } l->head = NULL; l->tail = NULL; l->len = 0; free(l); return 0;}int addNode(LinkedList *l, Node *n){ if (l == NULL || n == NULL) { return -1; } if (l->head == NULL) { l->head = n; } if (l->tail == NULL) { l->tail = n; } else { l->tail->next = n; l->tail = n; l->tail->next = NULL; } l->len++; return 0;}int delNode(LinkedList *l, Node *n){ if (l == NULL || n == NULL) { return -1; } if (l->head == n) { l->head = l->head->next; l->len--; if (l->len == 0) { l->tail = NULL; } return 0; } Node *temp = l->head; while (temp != NULL) { if (temp->next == n) { temp->next = temp->next->next; l->len--; if (l->len == 0) { l->tail = NULL; } return 0; } temp = temp->next; } return -1;}Node *getHeadNode(LinkedList *l){ if (l == NULL || l->head == NULL) { return NULL; } return l->head;}Node *getNextNode(LinkedList *l, Node *n){ if (l == NULL || n == NULL) { return NULL; } Node *temp = l->head; while (temp != NULL) { if (temp == n) { return temp->next; } temp = temp->next; } return NULL;}
cmdopt.c
#include "cmdopt.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>int initMenuData(LinkedList **l){ *l = initLinkedList(); CmdNode *p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "add"; p->handler = cmdAdd; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "minus"; p->handler = cmdMinus; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "multiply"; p->handler = cmdMultiply; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "divide"; p->handler = cmdDivide; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "quit"; p->handler = cmdQuit; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "showuid"; p->handler = cmdShowUID; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "help"; p->handler = cmdHelp; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = "hello"; p->handler = cmdHello; addNode(*l, (Node *)p); p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = ""; p->handler = cmdElse; addNode(*l, (Node *)p); return 0;}CmdNode *findCmd(LinkedList *l, char *cmd){ if (l == NULL || cmd == NULL) { return NULL; } CmdNode *p = (CmdNode *)getHeadNode(l); while (p != NULL) { if (strcmp(p->cmd, cmd) == 0) { return p; } p = (CmdNode *)getNextNode(l, (Node *)p); } p = l->tail; return p;}void cmdAdd(){ int a, b; printf(">>>"); scanf("%i", &a); printf(">>>"); scanf("%i", &b); printf(">>>%i\n", a + b);}void cmdMinus(){ int a, b; printf(">>>"); scanf("%i", &a); printf(">>>"); scanf("%i", &b); printf(">>>%i\n", a - b);}void cmdMultiply(){ int a, b; printf(">>>"); scanf("%i", &a); printf(">>>"); scanf("%i", &b); printf(">>>%i\n", a * b);}void cmdDivide(){ int a, b; printf(">>>"); scanf("%i", &a); printf(">>>"); scanf("%i", &b); printf(">>>%i\n", a / b);}void cmdHello(){ printf(">>>Welcome to shelllet!\n");}void cmdQuit(){ printf("**********Shelllet End**********\n"); exit(0);}void cmdShowUID(){ printf(">>>UID: %i\n", getuid());}void cmdHelp(){ printf("|help\n"); printf("|hello\n"); printf("|add\n"); printf("|minus\n"); printf("|multiply\n"); printf("|divide\n"); printf("|showuid\n"); printf("|quit\n");}void cmdElse(){ printf(">>>Wrong Commend\n");}
shelllet.c
#include "cmdopt.h"#include <stdio.h>#include <string.h>int main(){ LinkedList *l = NULL; initMenuData(&l); char cmd[128]; printf("**********Shelllet Running**********\n"); while (1) { printf(">>>"); scanf("%s", cmd); CmdNode *p = findCmd(l, cmd); if (p != NULL && p->handler != NULL) p->handler(); } return 0;}
运行效果
实验总结与问题
上周没看视频没想到居然分离是指加个链表,真是失败
我就一直在想为什么要弄个链表,链表本身是动态扩充的,但是到我们这个项目里链表所包含的内容(命令行的各种函数)都是写死在代码段里的,动态容器存储静态内容,加功能还是得重新编译,这不是南辕北辙么?
不过孟大师是厉害,这课上的总能有意想不到的收获
后来想考虑Linux的shell实现,它的各种功能都对应一个文件。建一个链表,每次都扫描某一目录中的所有文件,这样就比较合理,还能直接通过增减文件控制shell功能
不过这样可能就比较复杂,还是得用系统调用
所以简化了一下这个简单shell就变成这样了吧
阅读全文
0 0
- [高级软件工程实验]用可重用的链表模块来实现命令行菜单小程序V2.5
- 软件工程(C编码实践篇)”实验报告 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- “软件工程(C编码实践篇)”实验报告【实验四:用可重用的链表模块来实现命令行菜单小程序V2.5】
- 软件工程(C编码实践篇) 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 文章标题 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验报告四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5
- 用可重用的链表模块来实现命令行菜单小程序V2.5
- 用可重用的链表模块来实现命令行菜单小程序V2.5
- 判断手机是android还是ios,是否用了微信内置浏览器
- filebeat常见配置项梳理
- 数据丢失不用怕 iPhone手机数据备份方法分享
- 解决IE8固定宽度下拉列表中option内容显示不全问题
- python与mysql交互/读取本地配置文件/交互报错
- [高级软件工程实验]用可重用的链表模块来实现命令行菜单小程序V2.5
- 微积分之可微,可导,可积,连续之间的关系
- select函数及fd_set
- Battery Charging Specification 1.2 中文详解 USB
- win7使用putty报错已停止工作
- windows下安装的docker挂载window目录到docker容器
- xpath
- IDEA不能调试直接Disconnected
- ubuntu 安装tplink rtl8812au驱动