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

网易云ID:Nerd2dian0
源码:https://github.com/Nerd2dian0/Youcan/tree/master/lab6

实验要求:

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

实验过程:

实验楼克隆


实验结果演示:

实验代码(主要部分)

menu子系统设计接口:

int MenuConfig(char *cmd, char *desc, void (*handler)(int argc, char *argv[]));
//将具体的命令加入链表
int ExecuteMenu();
int Help(int argc, char **argv);
int Quit(int argc, char **argv);
makefile:
#
# Makefile for Menu Program
#

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

SRC     =  linkTable.c menu.c test.c
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
menu.c程序修改部分,实现自主添加命令和命令内容

int MenuConfig(char *cmd, char *desc, void (*handler)(int argc, char *argv[]))
{
    if(head == NULL)
    {
        head = CreateLinkTable();
        tDataNode *pNode = (tDataNode*) malloc(sizeof(tDataNode));
        pNode->cmd = "help";
        pNode->desc = "List all command in this program";
        pNode->handler = Help;
        AddLinkTableNode(head,(tLinkTableNode *)pNode);
    }
    tDataNode* pNode=(tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd=cmd;
    pNode->desc=desc;
    pNode->handler=handler;
    AddLinkTableNode(head,(tLinkTableNode *)pNode);
    return 0;
}

int ExecuteMenu()
{
    while(1)
    {
	int argc = 0;
	char *argv[CMD_MAX_ARGV_NUM];
        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;
        }
        /* convert cmd 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 = (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);
        }
    }
    return 0;
}

menu.h接口函数

//增添命令函数
int MenuConfig(char *cmd, char *desc, void (*handler)(int argc, char *argv[]));
//将具体的命令加入链表
int ExecuteMenu();
int Help(int argc, char **argv);
int Quit(int argc, char **argv);

getopt函数获取命令行参数

int Info(int argc, char** argv)
{
    opterr = 0;
    int oc;
    while((oc = getopt(argc, argv, "nv")) != -1)
      {
        switch(oc)
        {
            case 'n':
                printf("The author name is Nerd2dian0.\n");
                break;
            case 'v':
                printf("The version is 1.01.\n");
                break;
        }
    }
   optind = 0;	//如果没有这句,循环不在有用。
   return 0;
}
实验总结:完成一个命令行的接口函数,通过test.c可以自己输入想要的命令到链表中。学习 使用make和make clean来编译程序和清理自动生成的文件;学习 使用getopt函数获取命令行参数。受益匪浅!!






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值