子系统的可重用设计

来源:互联网 发布:上海大学乐乎论坛二手 编辑:程序博客网 时间:2024/04/29 12:54
【网易云课堂昵称:JaYiFen + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006 】

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

新创建一个目录lab7完成实验。

实验要求(参照视频中的具体实验过程)
  • 为menu子系统设计接口,并写用户范例代码来实现原来的功能;

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

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

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


1.实验思路:
  1. 根据老师的视频改写现有的代码;
  2. 编写makefile文件;
  3. 测试运行;
2.源代码:
  • menu.h
int MenuConfig(char *cmd, char *desc, int (*handler)(int argc, char* argv[]));int ExecuteMenu();

  • menu.c
/**************************************************************************************************//* Copyright (C) mc2lab.com, SSE@USTC, 2014-2015                                                  *//*                                                                                                *//*  FILE NAME             :  menu.c                                                               *//*  PRINCIPAL AUTHOR      :  Mengning                                                             *//*  SUBSYSTEM NAME        :  menu                                                                 *//*  MODULE NAME           :  menu                                                                 *//*  LANGUAGE              :  C                                                                    *//*  TARGET ENVIRONMENT    :  ANY                                                                  *//*  DATE OF FIRST RELEASE :  2014/08/31                                                           *//*  DESCRIPTION           :  This is a menu program                                               *//**************************************************************************************************//* * Revision log: * * Created by Mengning, 2014/08/31 * */#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 32tLinkTable * 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));        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 program */int ExecuteMenu(){    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;}

  • test.c
#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);    ExecuteMenu();    return 0;}

  • Makefile
  1 CC_FLAGS            = -c  2 CC_OUTPUT_FLAGS     = -o  3 CC                  = gcc  4 RM                  = rm  5 RM_FLAGS            = -f  6   7 TARGET  = test  8 OBJS    = linktable.o menu.o test.o  9  10 all:    $(OBJS) 11     $(CC)    $(CC_OUTPUT_FLAGS)    $(TARGET)    $(OBJS) 12  13 .c.o: 14     $(CC)    $(CC_FLAGS)    $< 15      16 clean: 17     $(RM)    $(RM_FLAGS)    $(OBJS)    $(TARGET)    *.bak

3.运行测试


4.GitHub



注:GitHub地址:点击打开链接

5.实验总结
实验中因为一个函数名打错了,找了很久的bug。了解了一些makefile基本的语法格式;

如有疑问欢迎交流!