将menu设计为可重用的子系统
2017-11-05 14:19
260 查看
网易云课堂昵称:风清扬pty
+《软件工程(C编码实践篇)》MOOC课程作业//mooc.study.163.com/course/USTC-1000002006
实验要求
为menu子系统设计接口,并写用户范例代码来实现原来的功能;
使用make和make clean来编译程序和清理自动生成的文件;
使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;
可以使用getopt函数获取命令行参数。
实验主要步骤及代码
创建Makefile文件,实现make指令编译功能。解决当项目中文件数目较多时,使用gcc 命令会很繁琐的问题。
menu.c可以使menu程序的升级和维护比较容易,具有重用性。
menu.h
test.c文件使用getopt函数获取命令行参数,使menu子系统支持带参数的复杂命令,可以丰富命令的内容。
实验结果
实验总结
学会了使用Makefile文件来简化多个文件的编译命令,但是一定注意使用Makefile时$开头的字符串之间要使用tab符号分开,不能使用空格,因为这个的疏忽前面好几次编译一直不通过。
学习了menu程序的可重用性。
编写代码时一定要认真,不要再因为粗心导致的错误检查修改好多次。
+《软件工程(C编码实践篇)》MOOC课程作业//mooc.study.163.com/course/USTC-1000002006
实验要求
为menu子系统设计接口,并写用户范例代码来实现原来的功能;
使用make和make clean来编译程序和清理自动生成的文件;
使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;
可以使用getopt函数获取命令行参数。
实验主要步骤及代码
创建Makefile文件,实现make指令编译功能。解决当项目中文件数目较多时,使用gcc 命令会很繁琐的问题。
CC_FLAGS = -c CC_OUTPUT_FLAGS = -o CC = gcc TARGET = test OBJS = linktable.o menu.o test.o RM = rm RM_FLAGS = -f all: $(OBJS) $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS) .c.o: $(CC) $(CC_FLAGS) $< clean: $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak
menu.c可以使menu程序的升级和维护比较容易,具有重用性。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "linktable.h" #include "menu.h" #define CMD_MAX_LEN 128 #define DESC_LEN 1024 #define CMD_NUM 10 #define CMD_MAX_ARGV_NUM 32 tLinkTable * head = NULL; int Help(int argc, char **argv); typedef struct DataNode { tLinkTableNode * pNext; char* cmd; char* desc; int (*handler)(int argc, char **argv); } tDataNode; int SearchCondition(tLinkTableNode * pLinkTableNode, void* args) { char* cmd = (char*)args; tDataNode * pNode = (tDataNode *)pLinkTableNode; if(strcmp(pNode->cmd, cmd) == 0) { return SUCCESS; } return FAILURE; } tDataNode* FindCmd(tLinkTable * head, char* cmd) { return (tDataNode*)SearchLinkTableNode(head, SearchCondition, cmd); } /* show all cmd in listlist */ int ShowAllCmd(tLinkTable * head) { tDataNode * pNode = (tDataNode*)GetLinkTableHead(head); while(pNode != NULL) { printf("%s\t - \t%s\n", pNode->cmd, pNode->desc); pNode = (tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode *)pNode); } return 0; } int MenuConfig(char *cmd, char *desc, int (*handler)(int argc, char **argv)) { tDataNode* pNode = NULL; if (head == NULL) { head = CreateLinkTable(); pNode = (tDataNode*)malloc(sizeof(tDataNode)); pN c795 ode->cmd = "help"; pNode->desc = "Menu List:"; pNode->handler = Help; AddLinkTableNode(head, (tLinkTableNode*)pNode); } pNode = (tDataNode*)malloc(sizeof(tDataNode)); pNode->cmd = cmd; pNode->desc = desc; pNode->handler = handler; AddLinkTableNode(head, (tLinkTableNode*)pNode); return 0; } /* menu program */ int ExcuteMenu() { while(1) { // init argc int argc = 0; char *argv[CMD_MAX_ARGV_NUM]; char cmd[CMD_MAX_LEN]; char *pcmd = NULL; // input cmd printf("Input a cmd > "); pcmd = fgets(cmd, CMD_MAX_LEN, stdin); if (pcmd == NULL) { continue; } // convert cmd line to argc/argv; pcmd = strtok(pcmd, " "); while (pcmd != NULL && argc < CMD_MAX_ARGV_NUM) { argv[argc] = pcmd; ++argc; pcmd = strtok(NULL, " "); } if (argc == 1) { int len = strlen(argv[0]); *(argv[0] + len - 1) = '\0'; } tDataNode *p = FindCmd(head, argv[0]); if( p == NULL) { printf("This is a wrong cmd!\n "); continue; } printf("%s\n", p->desc); if(p->handler != NULL) { p->handler(argc, argv); } } } int Help(int argc, char **argv) { printf("-------------------------------------------\n"); ShowAllCmd(head); printf("-------------------------------------------\n"); return 0; }
menu.h
int MenuConfig(char *cmd, char *desc, int (*handler)(int argc, char* argv[])); int ExecuteMenu();
test.c文件使用getopt函数获取命令行参数,使menu子系统支持带参数的复杂命令,可以丰富命令的内容。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "menu.h" int Quit(int argc, char **argv) { exit(0); } int argtest(int argc, char **argv) { const char *optString = "lah"; opterr = 0; int opt; while ((opt = getopt(argc, argv, optString)) != -1) { switch (opt) { case 'l': printf("this -l option\n"); break; case 'a': printf("this -a option\n"); break; case 'h': printf("in this cmd, you have 3 option can use:\n"); printf("-l\n"); printf("-a\n"); printf("-h\n"); break; default: break; } } // reset global valuable optind optind = 0; return 0; } int main(int argc, char **argv) { MenuConfig("version", "xxx v1.0(Menu program v1.0 inside)", NULL); MenuConfig("argtest", "test arg option", argtest); MenuConfig("quit", "quit from xxx", Quit); ExcuteMenu(); return 0; }
实验结果
实验总结
学会了使用Makefile文件来简化多个文件的编译命令,但是一定注意使用Makefile时$开头的字符串之间要使用tab符号分开,不能使用空格,因为这个的疏忽前面好几次编译一直不通过。
学习了menu程序的可重用性。
编写代码时一定要认真,不要再因为粗心导致的错误检查修改好多次。
相关文章推荐
- 高级软件工程实验7-----将menu设计为可重用的子系统
- 文章标题 实验七:将menu设计为可重用的子系统
- 实验报告七:将menu设计为可重用的子系统
- [高级软件工程实验]将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 软件工程(C编码实践篇)”实验报告实验七:将menu设计为可重用的子系统
- 实验报告七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验7 将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- 实验七:将menu设计为可重用的子系统
- “软件工程(C编码实践篇)”实验报告【实验七:将menu设计为可重用的子系统】
- MENU可重用的子系统
- 子系统的可重用设计
- Engine-Collection-Class,一种用来建立可重用企业组件的设计模式
- 输入子系统设计(4)