Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8990
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 182
  • 用 户 组: 普通用户
  • 注册时间: 2016-03-14 17:05
文章分类
文章存档

2017年(15)

2016年(3)

我的朋友

分类: 其他平台

2017-06-04 22:03:20

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

 【郭昌明 SA16225079 + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006

一 实验要求

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

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

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

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

二 实验环境

实验楼

三 实验步骤

1.在Code/shiyanlou_cs122目录下新创建一个目录lab7

2.将lab5的代码复制到lab7

$ cp -r lab5/* lab7

3.按照老师的视频中的思路修改代码,首先编写menu.h,代码如下:

图片描述

然后修改menu.c,主要是Menuconfig()和ExcuteMenu()这两个函数,代码如下

#include  #include  #include  #include "linktable.h" #include "menu.h" #define CMD_MAX_LEN 128 #define CMD_MAX_ARGV_LEN 128 #define DESC_LEN    1024 #define CMD_NUM     10 tLinkTable * head = NULL; void Help(int argc, char *argv[]); /* data struct and its operations */ typedef struct DataNode
{
    tLinkTableNode * pNext; char*   cmd; char*   desc; void (*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 MenuConfig(char * cmd, char * desc, void (*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);
} int ExecuteMenu()
{ while(1)
    { int argc = 0; char *argv[CMD_MAX_ARGV_LEN]; 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_LEN)
        {
            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 - %s\n", p->cmd, p->desc); if(p->handler != NULL) 
        { 
            p->handler(argc, argv);
        }
    }
} void Help(int argc, char *argv[])
{
    ShowAllCmd(head);
} 

然后编写test.c,代码如下:

#include  #include  #include  #include "menu.h" int Quit(int argc, char **argv) { exit(0);
} int Hello(int argc, char **argv) { printf("Hello! You are the best!"); return 1;
} int main(int argc, char **argv) {
    MenuConfig("version", "xxx v1.0(Menu program v3.0.0 inside)", NULL);
    MenuConfig("quit", "quit from the menu", Quit);
    MenuConfig("hello","hello cmd",Hello);
    ExcuteMenu(); return 0;
} 

然后编写MakeFile,代码如下:

#makefile for Menu Program CC_PTHREAD_FLAGS        = -lpthread
CC_FLAGS            = -c
CC_OUTPUT_FLAGS            = -o
CC_MATH                = -lm
CC                = gcc
RM                = rm
RM_FLAGS            = -f

TARGET    =    test
OBJS    =    linktable.o menu.o test.o all: $(OBJS)
    $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS) $(CC_MATH)

.c.o: $(CC) $(CC_FLAGS) $< clean: $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak 
  1. 编译运行 由于有Makefile文件,直接使用make命令即可进行编译

图片描述

四 实验结果

实验结果如下图:

图片描述

五 遇到的问题和解决方法

make的时候遇到报错,* missing separator. Stop.

通过网上查询资料,将命令行的空格,改成TAB键即可。因为在Makefile文件中,命令必须以【tab】键开始。

六 实验总结

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

通过本实验,了解menu程序设计为可重用子模块的过程,使menu子系统支持带参数的复杂命令,加深了对规范化编程的理解。

阅读(142) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册