[高级软件工程实验]将menu设计为可重用的子系统
来源:互联网 发布:好喝的洋酒推荐 知乎 编辑:程序博客网 时间:2024/04/20 19:48
版本库URL:https://github.com/swagnhen/Advanced-Software-Engineering-Exercise.git
实验要求
1)为menu子系统设计接口,并写用户范例代码来实现原来的功能;2)使用make和make clean来编译程序和清理自动生成的文件;3)使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;4)可以使用getopt函数获取命令行参数。
实验内容
callback增强可重用链表实现包含于linkedlist.h与linkedlist.c中
shell中各命令功能的实现包含在cmdopt.h与cmdopt.c中
main函数包含于shelllet.c中
编译时请使用
make
1.子系统设计接口
//用于用户向命令行添加新的命令功能int ShellletConfig(LinkedList *head, char * cmd, int (*handler)());//用于启动命令行程序int ExecuteShelllet(LinkedList *head);
具体实现
int ShellletConfig(LinkedList *l, char *cmd, int (*handler)()){ CmdNode *p = NULL; if (l == NULL) { return -1; } p = (CmdNode *)malloc(sizeof(CmdNode)); p->cmd = cmd; p->handler = handler; addNode(l, (Node *)p); return 0;}int ExecuteShelllet(LinkedList *l){ int argc = 0; char *argv[32]; printf("**********Shelllet Running**********\n"); while (1) { printf(">>>"); //cmd2arg函数用于将输入的命令转化为argc与argv形式 cmd2arg(&argc, argv); CmdNode *p = findCmd(l, argv[0]); if (p != NULL && p->handler != NULL) p->handler(argc, argv); argc = 0; } return 0;}
2.Makefile编译文件
## Makefile for Shelllet Program#CC_PTHREAD_FLAGS = -lpthreadCC_FLAGS = -c CC_OUTPUT_FLAGS = -oCC = gccRM = rmRM_FLAGS = -fTARGET = testOBJS = linkedlist.o cmdopt.o shelllet.oall: $(OBJS) $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS) .c.o: $(CC) $(CC_FLAGS) $<clean: $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak
3.复杂指令解析
void cmd2arg(int *argc, char **argv){ char cmd[1024]; char *pcmd = NULL; pcmd = fgets(cmd, 1024, stdin); if (pcmd == NULL) return; pcmd = strtok(pcmd, " "); while (pcmd != NULL && *argc < 32) { argv[*argc] = pcmd; (*argc)++; pcmd = strtok(NULL, " "); } if (*argc == 1) { int len = strlen(argv[0]); *(argv[0] + len - 1) = '\0'; }}
用户实现的复杂指令函数
int test(int argc, char *argv[]){ printf(">>>Test success\n"); return 0;}
4.获取命令行参
经cmd2arg处理后argv[1]开始均为命令行参数
void cmd2arg(int *argc, char **argv){ char cmd[1024]; char *pcmd = NULL; pcmd = fgets(cmd, 1024, stdin); if (pcmd == NULL) return; pcmd = strtok(pcmd, " "); while (pcmd != NULL && *argc < 32) { argv[*argc] = pcmd; (*argc)++; pcmd = strtok(NULL, " "); } if (*argc == 1) { int len = strlen(argv[0]); *(argv[0] + len - 1) = '\0'; }}
运行效果
实验总结
我对老师的写法做了一些修改,还是去掉了全局链表,这样的话每次用户(程序员)在使用这个程序的时候都得自己先建立一个链表,初始化之后再将链表传入ExecuteShelllet函数中执行命令行程序。
这样应该算是面向对象的实现思路吧,毕竟C中没有类,不能定义一个Menu类再向其添加start方法。
其实这个程序有bug,不论输什么命令第一次都会失效。
我调试之后发现是在第一次解析命令时字符串比对函数strcmp出现错误,没有返回正确结果的同时还改变了形参cmd的值。
就很神秘,这个函数的原型不是加了const么,怎么还能改变形参值的,还只出现一次。
感觉可能是头文件include的问题,之前在没加string.h的时候函数strtok也出现了一样的问题。
试了很多没有解决,就搁置了。
还有就是像加减乘除这样有指令执行中含有scanf调用的命令2,运行结束后程序会执行一个空指令(即“”)。
这个肯定是fget和scanf混用的问题,估计是add运行结束之后有个换行符\n还在输入流里,下一轮开始的时候被fget读到了。
虽然在每个scanf后面单独加个fget应该能解决,但是感觉这种方式非常蠢,也没想到更好的方式,就算了。
这程序再拓展几次估计就要不能维护了。
【Swegnhan + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006】
- 高级软件工程实验7-----将menu设计为可重用的子系统
- [高级软件工程实验]将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验7 将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 软件工程(C编码实践篇)”实验报告实验七:将menu设计为可重用的子系统
- “软件工程(C编码实践篇)”实验报告【实验七:将menu设计为可重用的子系统】
- 实验报告七:将menu设计为可重用的子系统
- 实验报告七:将menu设计为可重用的子系统
- 文章标题 实验七:将menu设计为可重用的子系统
- Hadoop 2.8 集群的安装
- jasperReports
- 面试中常见的排序算法
- 【数据建模 缺失值处理】缺失值的处理
- 从驱动层到应用层打通Android系统通路
- [高级软件工程实验]将menu设计为可重用的子系统
- Maven学习总结(四)——Maven核心概念
- 已经把用户加入MQ的执行用户组了,为什么该用户还是没有权限执行MQ
- PTA 爆内存函数实例
- java调用发送短信API
- itext pdf加水印
- 集成的HTTP嗅探器HttpWatch更新至v11.0.21,改进F5刷新机制
- Python with
- 算法导论学习-插入排序python实现