实验报告_ASE_lab7
来源:互联网 发布:淘宝分销商 编辑:程序博客网 时间:2024/06/05 19:02
昵称:fuguanqi 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006
实验七:将menu设计为可重用的子系统
实验要求
为menu子系统设计接口,并写用户范例代码来实现原来的功能;
使用make和make clean来编译程序和清理自动生成的文件;
使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;
可以使用getopt函数获取命令行参数。
实验步骤:
编写程序代码
撰写Makefile文件
编译测试
提交git
Coding版本库URL:https://git.coding.net/fuguanqi/ASE.git
关键问题总结
输入命令时,会将换行符存入命令的结尾,需要将命令字符串最后的换行符用‘\0‘替换掉。
多次调用Help函数时,getopt函数也会被多次调用,为了达到需求,必须在每次调用完Help函数时将getopt自身所带的全局变量optind进行归零,否则再次输入help命令或带选项的命令时,会影响程序的正常功能,并产生段错误。
源代码
menu.c
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include "linktable.h"tLinkTable * head = NULL;int Help();#define CMD_MAX_LEN 1024#define CMD_MAX_ARGV_NUM 32#define DESC_LEN 1024#define CMD_NUM 10//char cmd[CMD_MAX_LEN];/* data struct and its operations */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; }/* find a cmd in the linklist and return the datanode pointer */tDataNode* FindCmd(tLinkTable * head, char * cmd){ return (tDataNode*)SearchLinkTableNode(head,SearchCondition,(void*)cmd);}/* 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;/* add cmd to menu */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)); pNode->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 Engine Execute */int ExecuteMenu(){ //InitMenuData(&head); /* cmd line begins */ while(1) { int argc = 0; char * argv[CMD_MAX_ARGV_NUM]; char cmd[CMD_MAX_LEN]; char * pcmd = NULL; printf("Input a cmd > "); //scanf("%s", cmd); //tDataNode *p = (tDataNode*)SearchLinkTableNode(head,SearchCondition,(void*)cmd); pcmd = fgets(cmd, CMD_MAX_LEN, stdin); if( pcmd == NULL) { //printf("This is a wrong cmd!\n "); continue; } // 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'; // } int i; for(i = 0 ; i < argc ; i++ ) { if (i==argc-1) //replace the line break with "\0" { int len = strlen(argv[i]); *(argv[i] + len - 1) = '\0'; } } tDataNode *p = (tDataNode*)SearchLinkTableNode(head,SearchCondition,(void*)argv[0]); if( p == NULL) { printf("This is a wrong cmd!\n"); continue; } if(p->handler != NULL) { p->handler(argc,argv); } printf("%s - %s\n", p->cmd, p->desc); }}static const char *optString = "abcde";int Help(int argc, char * argv[]){ ShowAllCmd(head); int opt; while((opt = getopt (argc, argv,optString)) != -1) { switch (opt) { case 'a' : printf ("\nOption a\n\n" ); break ; case 'b' : printf ("\nOption b\n\n" ); break ; case 'c' : printf ("\nOption c\n\n"); break ; case 'd' : printf ("\nOption d\n\n" ); break ; case 'e' : printf ("\nOption e\n\n" ); break ; } } optind=0; //reset the function getopt return 0; }
test.c
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include"menu.h"int Quit(int argc, char * argv[]){ /* add XXX clean ops */ exit(0);}int main (){ MenuConfig("version","XXX V1.0(Menu program v1.0 inside)", NULL); MenuConfig("quit","Quit from XXX", Quit); ExecuteMenu();}
Makefile
CC_PTHREAD_FLAGS = -lpthreadCC_FLAGS = -cCC_OUTPUT_FLAGS = -oCC = gccRM = rmRM_FLAGS = -fTARGET = test1OBJS = linktable.o menu.o test.oall: $(OBJS) $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS).c.o: $(CC) $(CC_FLAGS) $<clean: $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak
阅读全文
0 0
- 实验报告_ASE_lab7
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 实验报告
- 第二次实验 实验报告
- 实验五:实验报告
- 《数据结构》实验一 实验报告
- 数据结构 实验一实验报告
- Ubuntu16.04+hadoop2.8.2搭建伪分布式
- int和Integer解析
- centos 7 rhel7怎么用mail发送邮件 到163 外部邮箱
- js 练习
- OpenGL基础及学习(.obj .frag .vert .mtl文件)(1)
- 实验报告_ASE_lab7
- 从零开始python案例005竞猜四个数字
- POI模版打印
- Linux安装activemq
- 求一个int型二进制数中1的个数
- 基于Unity3D的虚拟摇杆的实现
- advanced rest client 谷歌测试工具安装
- 函数的调用过程、栈帧的创建以及销毁
- 【日志】最后的时光②