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

将menu设计为可重用的子系统
学号:SA17225091
姓名:龚雨濛
github:https://github.com/lgddd/gr_lab

1. 实验要求

  1. 为menu子系统设计接口,并写用户范例代码来实现原来的功能;
  2. 使用make和make clean来编译程序和清理自动生成的文件;
  3. 使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;
  4. 可以使用getopt函数获取命令行参数;
2. 实验过程

  • 新建lab7文件夹
  • 拷贝lab5文件至lab7
  • 新建 menu.h
#ifndef _menu
#define _menu
int MenuConfig(char* cmd, char* desc, int (*handler)());
int ExecuteMenu();
#endif
  • 新建Makefile文件
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:    $(OBJS)
   $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS)

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

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

用ExcuteMenu取代main函数并作相应修改

int ExecuteMenu()
{
   //InitMenuData(&head); 
   //char cmd[81];
  /* cmd line begins */
   while(1)
   {
       //char cmd[CMD_MAX_LEN];
       int argc = 0;
       char *argv[CMD_MAX_ARGV_LEN];
       //char cmd[CMD_MAX_LEN];
       char *pcmd = NULL;
       printf("Input a cmd number > ");
       //scanf("%s", cmd);
       pcmd = fgets(cmd, CMD_MAX_LEN, stdin);

       if(pcmd == NULL)
       {
           continue;
       }

       pcmd = strtok(pcmd, " ");

       while(pcmd != NULL && argc < CMD_MAX_ARGC_LEN)
       {
           printf("%s\n", pcmd);
           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);
       }
     }
     }
  • 修改ExcuteConfig
int MenuConfig(char *cmd, char *desc, int (*handler)(int argc, char *argv[]))
{
   tDataNode *pNode = NULL;
   if(head == NULL)
   {
       head = (tLinkTable *)CreateLinkTable();
       pNode = (tDataNode *)malloc(sizeof(tDataNode));
       pNode->cmd = "help";
       pNode->desc = "Help 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);
}
  • 新建test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "linktable.h"
#include "menu.h"
/*
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
*/
int Quit(int argc, char* argv[]);
int main(int argc, char* argv[])
{
   MenuConfig("version", "Menu Program V3.0", NULL);
   MenuConfig("quit", "Quit from Menu Program V3.0", Quit);
   ExecuteMenu();
}
int Quit(int argc, char* argv[])
{
   int oc;
   char *b_opt_arg;
   while((oc = getopt(argc, argv, "cl:\n")) != -1)
   {
       switch(oc)
       {
           case 'c':
               printf("Clean Success,exiting\n");
               //delay(2000);
               sleep(2);
               break;
           case 'l':
               b_opt_arg = optarg;
               printf("Log :%s\n",optarg);
               //delay(2000);
               sleep(2);
               break;
           case '\n':
               break;
       }
   }
   exit(0);
}
3.实验心得与总结

  • 本次实验通过为menu设计子系统接口,进一步提高了menu小程序的可重用性和模块化。Makefile的使用实现了自动化的脚本,省去了每次敲很多的编译命令。
  • 模块化的思想有利于提高编程的可重用性和效率。以后我也会把这种思想运用其他代码的编写中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值