zoukankan      html  css  js  c++  java
  • 软件工程实验7

    实验报告7

    网易云课堂昵称:哪来的妖精

    网易云课堂《软件工程(C编码实践篇)》MOOC课程作业:http://mooc.study.163.com/learn/USTC-1000002006

    github   https://github.com/littlewulei/Software-Engineering-Lab.git

    实验要求

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

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

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

    实验步骤

    创建lab7文件夹。创建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

    需要注意的是Makefile 需要用Tab缩进,空格不行。

    linktable.h代码如下:

    #ifndef _LINK_TABLE_H_
    #define _LINK_TABLE_H_
    #include <pthread.h>
    #define SUCCESS 0
    #define FAILURE (-1)
    /*
     * LinkTable Node Type
     */
    typedef struct LinkTableNode tLinkTableNode;
    /*
     * LinkTable Type
     */
    typedef struct LinkTable tLinkTable;
    /*
     * Create a LinkTable
     */
    tLinkTable * CreateLinkTable();
    /*
     * Delete a LinkTable
     */
    int DeleteLinkTable(tLinkTable *pLinkTable);
    /*
     * Add a LinkTableNode to LinkTable
     */
    int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode);
    /*
     * Delete a LinkTableNode from LinkTable
     */
    int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode);
    /*
     * Search a LinkTableNode from LinkTable
     * int Conditon(tLinkTableNode * pNode);
     */
    tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args);
    /*
     * get LinkTableHead
     */
    tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);
    /*
     * get next LinkTableNode
     */
    tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode);
    #endif /* _LINK_TABLE_H_ */

    linktable.c文件如下:

    #include<stdio.h>
    #include<stdlib.h>
    #include"linktable.h"
    typedef struct LinkTableNode
    {
        struct LinkTableNode * pNext;
    }tLinkTableNode;
    typedef struct LinkTable{
        tLinkTableNode *pHead;
        tLinkTableNode *pTail;
        int            SumOfNode;
        pthread_mutex_t mutex;
    }tLinkTable;
    /*
     * Create a LinkTable
     */
    tLinkTable * CreateLinkTable()
    {
        tLinkTable * pLinkTable = (tLinkTable *)malloc(sizeof(tLinkTable));
        if(pLinkTable == NULL)
        {
            return NULL;
        }
        pLinkTable->pHead = NULL;
        pLinkTable->pTail = NULL;
        pLinkTable->SumOfNode = 0;
        pthread_mutex_init(&(pLinkTable->mutex), NULL);
        return pLinkTable;
    }
    /*
     * Delete a LinkTable
     */
    int DeleteLinkTable(tLinkTable *pLinkTable)
    {
        if(pLinkTable == NULL)
        {
            return FAILURE;
        }
        while(pLinkTable->pHead != NULL)
        {
            tLinkTableNode * p = pLinkTable->pHead;
            pthread_mutex_lock(&(pLinkTable->mutex));
            pLinkTable->pHead = pLinkTable->pHead->pNext;
            pLinkTable->SumOfNode -= 1 ;
            pthread_mutex_unlock(&(pLinkTable->mutex));
            free(p);
        }
        pLinkTable->pHead = NULL;
        pLinkTable->pTail = NULL;
        pLinkTable->SumOfNode = 0;
        pthread_mutex_destroy(&(pLinkTable->mutex));
        free(pLinkTable);
        return SUCCESS;        
    }
    /*
     * Add a LinkTableNode to LinkTable
     */
    int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
    {
        if(pLinkTable == NULL || pNode == NULL)
        {
            return FAILURE;
        }
        pNode->pNext = NULL;
        pthread_mutex_lock(&(pLinkTable->mutex));
        if(pLinkTable->pHead == NULL)
        {
            pLinkTable->pHead = pNode;
        }
        if(pLinkTable->pTail == NULL)
        {
            pLinkTable->pTail = pNode;
        }
        else
        {
            pLinkTable->pTail->pNext = pNode;
            pLinkTable->pTail = pNode;
        }
        pLinkTable->SumOfNode += 1 ;
        pthread_mutex_unlock(&(pLinkTable->mutex));
        return SUCCESS;        
    }
    /*
     * Delete a LinkTableNode from LinkTable
     */
    int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
    {
        if(pLinkTable == NULL || pNode == NULL)
        {
            return FAILURE;
        }
        pthread_mutex_lock(&(pLinkTable->mutex));
        if(pLinkTable->pHead == pNode)
        {
            pLinkTable->pHead = pLinkTable->pHead->pNext;
            pLinkTable->SumOfNode -= 1 ;
            if(pLinkTable->SumOfNode == 0)
            {
                pLinkTable->pTail = NULL;    
            }
            pthread_mutex_unlock(&(pLinkTable->mutex));
            return SUCCESS;
        }
        tLinkTableNode * pTempNode = pLinkTable->pHead;
        while(pTempNode != NULL)
        {    
            if(pTempNode->pNext == pNode)
            {
                pTempNode->pNext = pTempNode->pNext->pNext;
                pLinkTable->SumOfNode -= 1 ;
                if(pLinkTable->SumOfNode == 0)
                {
                    pLinkTable->pTail = NULL;    
                }
                pthread_mutex_unlock(&(pLinkTable->mutex));
                return SUCCESS;                    
            }
            pTempNode = pTempNode->pNext;
        }
        pthread_mutex_unlock(&(pLinkTable->mutex));
        return FAILURE;        
    }
    /*
     * Search a LinkTableNode from LinkTable
     * int Conditon(tLinkTableNode * pNode);
     */
    tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args)
    {
        if(pLinkTable == NULL || Conditon == NULL)
        {
            return NULL;
        }
        tLinkTableNode * pNode = pLinkTable->pHead;
        while(pNode != NULL)
        {    
            if(Conditon(pNode, args) == SUCCESS)
            {
                return pNode;                    
            }
            pNode = pNode->pNext;
        }
        return NULL;
    }
    /*
     * get LinkTableHead
     */
    tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable)
    {
        if(pLinkTable == NULL)
        {
            return NULL;
        }    
        return pLinkTable->pHead;
    }
    /*
     * get next LinkTableNode
     */
    tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
    {
        if(pLinkTable == NULL || pNode == NULL)
        {
            return NULL;
        }
        tLinkTableNode * pTempNode = pLinkTable->pHead;
        while(pTempNode != NULL)
        {    
            if(pTempNode == pNode)
            {
                return pTempNode->pNext;                    
            }
            pTempNode = pTempNode->pNext;
        }
        return NULL;
    }

    menu.h :

    #ifndef _MENU_H
    #define _MENU_H
    
    int MenuConfig(char * cmd, char * desc, void (*handler)(int argc, char *argv[]));
    
    int ExecuteMenu();
    
    #endif

    menu.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "linktable.h"
    #include "menu.h"
    #define CMD_MAX_LEN 128
    #define CMD_MAX_ARGV_LEN 128
    #define DESC_LEN    1024
    #define CMD_NUM     10
    
    
    tLinkTable * head = NULL;
    void Help(int argc, char *argv[]);
    
    /* data struct and its operations */
    
    typedef struct DataNode
    {
        tLinkTableNode * pNext;
        char*   cmd;
        char*   desc;
        void    (*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;           
    }
    
    /* 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
    ", pNode->cmd, pNode->desc);
            pNode = (tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode *)pNode);
        }
        return 0;
    }
    
    int MenuConfig(char * cmd, char * desc, void (*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);
    }
    
    int ExecuteMenu()
    {
        while(1)
        {
            int argc = 0;
            char *argv[CMD_MAX_ARGV_LEN];
            char cmd[CMD_MAX_LEN];
            char *pcmd = NULL;
            printf("Input a cmd number > ");
            pcmd = fgets(cmd, CMD_MAX_LEN, stdin);
            if (pcmd == NULL)
            {
                continue;
            }
            pcmd = strtok(pcmd, " ");
            while (pcmd != NULL && argc < CMD_MAX_ARGV_LEN)
            {
                argv[argc] = pcmd;
                argc++;
                pcmd = strtok(NULL, " ");
            }
            if (argc == 1)
            {
                int len = strlen(argv[0]);
                *(argv[0] + len - 1) = '';
            }
    
            tDataNode *p = FindCmd(head, argv[0]);
            if( p == NULL)
            {
                printf("This is a wrong cmd!
     ");
                continue;
            }
            printf("%s - %s
    ", p->cmd, p->desc); 
            if(p->handler != NULL) 
            { 
                p->handler(argc, argv);
            }
        }
    }
    void Help(int argc, char *argv[])
    {
        ShowAllCmd(head);
    }

    test.c :

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include "menu.h"
    
    void Quit(int argc, char *argv[]);
    void Version(int argc, char *argv[]);
    
    void Quit(int argc, char *argv[])
    {
        exit(0);
    }
    
    void Version(int argc, char *argv[])
    {
        printf("version7.0
    ");
    }
    
    void Date(int argc, char *argv[])
    {
    
        system("date");
    }
    
    int Add(int argc, char* argv[])
    {
        int i,r;
        if(argc != 3)
        {
            printf("warning input 2 numbers
    ");
            return 0;
        }
        r=atoi(argv[1])+atoi(argv[2]);
        printf("result is %d
    ",r);
        return 0;
    }
    
    int Sub(int argc, char* argv[])
    {
        int i,r;
        if(argc !=3)
        {
            printf("warning input 2 numbers
    ");
            return 0;
        }
        r=atoi(argv[1])-atoi(argv[2]);
        printf("result is %d
    ",r);
        return 0;
    }
    
    int Mul(int argc, char* argv[])
    {
        int i,r;
        if(argc !=3)
        {
            printf("warning input 2 numbers
    ");
            return 0;
        }
        r=atoi(argv[1])*atoi(argv[2]);
        printf("result is %d
    ",r);
        return 0;
    }
    
    int Divi(int argc, char* argv[])
    {
        int i;
        float r;
        if(argc !=3)
        {
            printf("warning input 2 numbers
    ");
            return 0;
        }
        r=((float)atoi(argv[1]))/atoi(argv[2]);
        printf("result is %.2f
    ",r);
        return 0;
    }
    
    int main(int argc,char* argv[])
    {
        MenuConfig("version","XXX1.0(Menu program v7.0 inside)",NULL);
        MenuConfig("quit","Quit from XXX",Quit);
        MenuConfig("date","Show the date",Date);
        MenuConfig("add","return sum of the two numbers", Add);
        MenuConfig("sub","return difference of the two numbers", Sub);
        MenuConfig("mul","return product of the two numbers", Mul);
        MenuConfig("divi","return quotient of the two numbers", Divi);
        ExecuteMenu();
    }

    运行截图

    上传GitHub

    实验总结

    这次实验彻底将menu小程序编写成为一个可重用的小程序供其他程序使用,实现了代码的可重用性,并且学会了使用Makefile 编译代码。

  • 相关阅读:
    20、Windows API 进程间通信,邮槽(Mailslot)
    15、Windows API 线程同步
    11、Windows API 内存管理(1)
    17、Windows API 图形用户界面(1)
    16、Windows API 服务
    12、Windows API 内存管理(2)
    19、Windows API 系统信息
    Oracle: 四、Oracle连接查询,子查询(相关子查询,嵌套子查询)(下)
    OpenSource: “一个开源的留言系统”,欢迎加入,共同开发
    Oracle: 四、对scott用户的基本查询操作(上篇)
  • 原文地址:https://www.cnblogs.com/raincute/p/7788871.html
Copyright © 2011-2022 走看看