您的位置:首页 > 其它

实验七:将menu设计为可重用的子系统

2017-11-03 01:06 435 查看

一、实验要求

为menu子系统设计接口,并写用户范例代码来实现原来的功能;

使用make和make clean来编译程序和清理自动生成的文件;

使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;

可以使用getopt函数获取命令行参数。

二、实验过程

本次实验中所用版本库地址为:https://github.com/WhiteWhiteW/se_2017.git

使用mkdir命令创建lab7目录

为menu子系统设计接口,并写用户范例代码来实现原来的功能。

具体代码修改如下

修改menu.c文件

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "linktable.h"

#include "menu.h"

tLinkTable *head = NULL;

#define CMD_MAX_LEN         128

#define DESC_LEN            1024

#define CMD_NUM             10

#define CMD_MAX_ARGV_NUM    10

/* 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 Help(int argc, char *argv[])
{
ShowAllCmd(head);
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));
pNode->cmd = "help";
pNode->desc = "This is help cmd!";
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;
}

int ExecuteMenu()
{
/* 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 number > ");
pcmd = fgets(cmd, CMD_MAX_LEN, stdin);
if(pcmd == NULL)
{
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';
}
tDataNode *p  = (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void*)argv[0]);
//tDataNode *p = FindCmd(head,argv[0]);
if(p == NULL)
{
printf("This is a wrong cmd!\n");
continue;
}
printf("%s - %s\n",p->cmd,p->desc);
if(p->handler != NULL)
{
p->handler(argc, argv);
}
}
return 0;
}


编辑menu.h文件

#ifndef _MENU_H_

#define _MENU_H_

/* add cmd to menu */
int MenuConfig(char* cmd, char* desc, int (*handler)());

/* Menu Engine Execute */
int ExecuteMenu();

#endif /* _MENU_H_ */


编写test.c文件

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <time.h>

#include "linktable.h"

#include "menu.h"

int Time(int argc, char *argv[])
{
time_t t = time(0);
char temp[64];
strftime(temp, sizeof(temp), "%Y/%m/%d %X %A", localtime(&t));
puts(temp);
return 0;
}

int Quit(int argc, char *argv[])
{
exit(0);
}

int main(int argc, char *argv[])
{
MenuConfig("version", "menu program v3.0", NULL);
MenuConfig("time", "this is time cmd!", Time);
MenuConfig("quit", "this is quit cmd!", Quit);

ExecuteMenu();
return 0;
}


编写makefile文件,达到使用make和make clean来编译程序和清理自动生成的一系列文件的目的

#

# Makefile for Menu Program

#

CC_PTHREAD_FLAGS    =   -lpthread
CC_FLAGS    =   -c
CC_OUTPUT_FLAGS =   -o
CC  =   gcc
RM  =   rm
RM_FLAGS    =   -f

TARGET  =   test
OBJS    =   linktable.o menu.o test.o

all:    $(TARGET)   clean
$(TARGET):    $(OBJS)
$(CC)   $(CC_OUTPUT_FLAGS)  $(TARGET)   $(OBJS)

.c.o:
$(CC)   $(CC_FLAGS) $<

.PHONY:clean

clean:
$(RM)   $(RM_FLAGS) $(OBJS) *.bak


三、实验结果

使用make指令验证,并使用./test指令运行。结果如下图所示。



四、遇到的问题及解决办法

编译遇到错误
*** missing separator. Stop.


错误分析:makefile文件中命令间应该使用tab键分隔



五、提交到github

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: