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

来源:互联网 发布:淘宝代销怎么编辑宝贝 编辑:程序博客网 时间:2024/05/29 08:54

一、实验要求

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。


原创粉丝点击