SA17225160_李伯威(libowei)_高级软工第六次实验报告

一、实验要求

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

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

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

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

二、实验内容

1.clone并进入共享文件夹


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

1)用vim编写menu.h的代码:


2)用vim编写menu.c的代码:

具体代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "linktable.h"
#include "menu.h"

#define CMD_MAX_LEN 128
#define DESC_LEN    1024
#define CMD_NUM     10


/* data struct and its operations */

typedef struct DataNode
{
    tLinkTableNode * pNext;
    char*   cmd;
    char*   desc;
    int     (*handler)(int agrc, char* agrv[]);
} tDataNode;

tLinkTable * head = NULL;

int SearchCondition(tLinkTableNode * pLinkTableNode, void* args)
{
    tDataNode * pNode = (tDataNode *)pLinkTableNode;
    char* cmd = (char*)args;
    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()
{
    printf("**************************help****************************\n");
    printf("List all the cmd of menu program:\n");
    ShowAllCmd(head);
    printf("**************************end*****************************\n");
}

int MenuConfig(char* cmd, char* desc, int (*handler)(int agrc, char* agrv[]))
{
    if(head == NULL)
    {
        head = CreateLinkTable();
        tDataNode* pNode = (tDataNode*)malloc(sizeof(tDataNode));
        pNode->cmd = "help";
        pNode->desc = "List all the cmd of menu";
        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()
{
   /* cmd line begins */
    char input[CMD_MAX_LEN];

    printf("gitDongHub menu [version 3.0]\n");
    printf("gitDongHub@copyright at 2017/09/24\n");
    printf("If you need help, please type help\n");
    while(1)
    {
	int agrc = 0;
	char* agrv[CMD_MAX_LEN];
	char* cmd = NULL;

    	printf("cmd>>");
    	cmd = fgets(input, CMD_MAX_LEN, stdin);
	
	if(cmd == NULL)
	{
	    continue;
	}

	/*converts cmd to agrc and agrv*/
	cmd = strtok(cmd, " ");
	while(cmd != NULL && agrc < CMD_MAX_LEN)
	{
	    agrv[agrc] = cmd;
	    agrc ++;
            cmd = strtok(NULL, " ");
	}
	if(agrc ==  1)
	{
	    int len = strlen(agrv[0]);
	    *(agrv[0] + (len - 1)) = '\0';
	} 
    	tDataNode* p = FindCmd(head, agrv[0]);
        if(p == NULL)
        {
            printf("the cmd you input isn't exist\n");
            continue;
        }
        if(p->handler != NULL)
        {
            p->handler(agrc, agrv);
        }
	   
    }
    return 0;
}

3)编写test.c作为用户执行接口,使用getopt函数获取命令行参数,使menu子系统支持带参数的复杂命令。

具体代码如下:

#include <stdio.h>
#include <stdlib.h>
#include "menu.h"
#include "linktable.h"

int quit();
int echo(int argc, char* argv[]);

int main(int argc, char* argv)
{
    MenuConfig("quit","quit from the menu program", quit);
    MenuConfig("echo","printf all you input in the terminal", echo);
    ExecuteMenu();

    return 0;
}

int quit()
{
    exit(0);
    
    return 0;
}

int echo(int argc, char* argv[])
{
    int i;
    if(argc == 1)
    {
        printf("echo on\n");
    }
    
    for(i = 1;i < argc;i ++)
    {
        printf("%d:%s\n",i, argv[i]);
    }
    return 0;
}

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

1)编写Makefile文件


2)用make命令进行编译:


3)生成的文件如下:


4)运行test的结果:

5.将代码push到GitHub


push成功



我的github地址:https://github.com/lili0001002/cs122/tree/master/lab7

三、实验收获

  • 知道了当编译的文件较多时,可以使用Makefile来简化编译过程。Makefile工程文件也是代码,要考虑可维护性。
  • 通过编写menu接口,可以提高menu子系统的可重用性。
  • 知道了如何利用argc,argv和getopt来处理命令行参数。从而使得用户对命令行有更多的更精确的控制。
  • gets存在缓冲区溢出的问题,所以程序不能用gets的而是用fgets。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值