实验7

来源:互联网 发布:ubuntu 16.04 ppa失败 编辑:程序博客网 时间:2024/06/08 06:58

火页凡 + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006

一.     实验过程

Clonegithub库:github.com/wangyufan/SE.git到实验环境

1.进入实验目录并创建实验一文件夹lab7


2.修改linktable.h,linktable.c,menu.c,menu.h文件,新增test.c

在menu.c中去掉main函数并增加函数MenuConfig和ExecuteMenu,作为接口使用以增加通用性;
将原menu.c中的功能性代码搬入新的test.c中,为了代码的使用简洁,采用了最初加入各个命令的形式,首先写入数据结构;
使用make和make clean来编译程序和清理自动生成的文件;
使menu子系统支持带参数的复杂命令,使用了getopt函数来获取命令行参数;
代码如下:
#ifndef _LINK_TABLE_H_#define _LINK_TABLE_H_#define SUCCESS 0#define FAILURE (-1)typedef struct LinkTableNode{    struct LinkTableNode* pNext;}tLinkTableNode;//信息隐藏typedef struct LinkTable tLinkTable;tLinkTable* CreateLinkTable();int DeleteLinkTable(tLinkTable* pLinkTable);int AddLinkTableNode(tLinkTable* pLinkTable, tLinkTableNode* pNode);int DelLinkTableNode(tLinkTable* pLinkTable, tLinkTableNode* pNode);tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode,void* args), void* args);tLinkTableNode* GetLinkTableHead(tLinkTable* pLinkTable);tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode);#endif /* _LINK_TABLE_H_ */#include #include #include "linktable.h"//信息隐藏typedef struct LinkTable{    tLinkTableNode *pHead;    tLinkTableNode *pTail;    int sumOfNode;}tLinkTable;tLinkTable* CreateLinkTable(){    tLinkTable* pLinkTable = (tLinkTable*)malloc(sizeof(tLinkTable));    if(pLinkTable == NULL)    {        return NULL;    }    pLinkTable->pHead = NULL;    pLinkTable->pTail = NULL;    pLinkTable->sumOfNode = 0;    return pLinkTable;}int DeleteLinkTable(tLinkTable* pLinkTable){    if(pLinkTable == NULL)    {        return FAILURE;    }    while(pLinkTable->pHead != NULL)    {        tLinkTableNode* pNode = pLinkTable->pHead;        pLinkTable->pHead = pLinkTable->pHead->pNext;        free(pNode);      }     pLinkTable->pHead = NULL;    pLinkTable->pTail = NULL;    pLinkTable->sumOfNode = -1;    free(pLinkTable);    return SUCCESS;}int AddLinkTableNode(tLinkTable* pLinkTable, tLinkTableNode* pNode){    if (pLinkTable == NULL || pNode == NULL)    {        return FAILURE;    }    pNode->pNext = NULL;    if (pLinkTable->pHead == NULL)    {        pLinkTable->pHead = pNode;    }    if (pLinkTable->pTail == NULL)    {        pLinkTable->pTail = pNode;    }    else    {        pLinkTable->pTail->pNext = pNode;        pLinkTable->pTail = pNode;    }    pLinkTable->sumOfNode = pLinkTable->sumOfNode + 1;    return SUCCESS;}int DelLinkTableNode(tLinkTable* pLinkTable, tLinkTableNode* pNode){    if (pLinkTable == NULL || pNode == NULL)    {        return FAILURE;    }    if (pLinkTable->pHead == pNode)    {        pLinkTable->pHead = pLinkTable->pHead->pNext;        pLinkTable->sumOfNode = pLinkTable->sumOfNode - 1;        if (pLinkTable->sumOfNode == 0)        {            pLinkTable->pTail == NULL;        }        return SUCCESS;    }    tLinkTableNode* p = pLinkTable->pHead;    while (p != NULL)    {        if (p->pNext == pNode)        {            p->pNext = p->pNext->pNext;            pLinkTable->sumOfNode = pLinkTable->sumOfNode - 1;            if (pLinkTable->sumOfNode == 0)            {                pLinkTable->pTail = NULL;            }            return SUCCESS;        }        p = p->pNext;    }    return FAILURE;}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;}tLinkTableNode* GetLinkTableHead(tLinkTable* pLinkTable){    if (pLinkTable == NULL || pLinkTable->pHead == NULL)    {        return NULL;    }    return pLinkTable->pHead;}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;}#ifndef _MENU_H#define _MENU_Hint MenuConfig(char *cmd, char *desc, int(*handler)());int ExecuteMenu();#endif#include #include #include #include #include "linktable.h"#include "menu.h"#define CMD_MAX_LEN 128#define DESC_LEN 1024#define CMD_MAX_ARGV_LEN 16typedef struct DataNode{    tLinkTableNode* pNext;    char* cmd;    char* desc;    int (*handler)(int argc, char* argv[]);}tDataNode;tLinkTable* head = NULL;int SearchCondition(tLinkTableNode * pLinkTableNode, void* args){    char* cmd = (char*)args;    tDataNode * pNode = (tDataNode *)pLinkTableNode;    if(strcmp(pNode->cmd, cmd) == 0)    {        return  SUCCESS;      }    return FAILURE;       }tDataNode* FindCmd(tLinkTable* head, char* cmd){    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition,cmd);}int ShowAllCmd(tLinkTable* head){    tDataNode* pNode = (tDataNode*) GetLinkTableHead(head);    while(pNode != NULL)    {        printf("%10s   -----   %s\n", pNode->cmd, pNode->desc);        pNode = (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)pNode);    }    return 0;}int Help(int argc, char* argv[]){    int ch;    char* ch_prom;printf("*************************************************************\n");    if(argc ==1)    {        ShowAllCmd(head);        return 0;    }    while((ch = getopt(argc, argv, "shl:")) != -1)    {        switch(ch)        {            case 's':                printf("This is \"-s\" mode help\n");                break;            case 'h':                printf("This is \"-h\" mode help\n");                break;            case 'l':                ch_prom = optarg;                printf("This is \"-l\" mode help with %s\n", ch_prom);                break;            case '?':                printf("Wrong argument!\n");        }    }    optind = 1;printf("*************************************************************\n");    return 0;}int MenuConfig(char* cmd, char* desc, int(*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);    return 0; }int ExecuteMenu(){    while(1)    {        int argc = 0;        char *argv[CMD_MAX_ARGV_LEN];        char cmd[CMD_MAX_LEN];        char *pcmd = NULL;        printf("menu cmd-> ");        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) = '\0';        }                  tDataNode* p = FindCmd(head, argv[0]);              if(p == NULL)        {            continue;        }         if(p->handler != NULL)        {            p->handler(argc, argv);        }    }    return 0;}#include #include #include #include "linktable.h"#include "menu.h"typedef struct CMDNode{    char* cmd;    char* desc;    int(*handler)(int argc, char* argv[]);}tCMDNode;int help(int argc, char* argv[]);int version(int argc, char* argv[]);int quit(int argc, char* argv[]);int multi(int argc, char* argv[]);int sub(int argc, char* argv[]);int add(int argc, char* argv[]);int lower(int argc, char* argv[]);int upper(int argc, char* argv[]);tCMDNode dHead[] ={    {"help", "cmd tips.", help},    {"version","show version of this menu.",version},    {"quit", "exit cmd.",quit},    {"upper", "change the case into uppercase Letters.",upper},    {"lower", "change the case into lowercase Letters.",lower},    {"sub", "subtraction of two numbers.",sub},    {"add", "addition of two numbers.",add},    {"multi", "multiplication of two numbers.", multi}};int numOfCmdExHelp = sizeof(dHead) / sizeof(dHead[0]);int InitMenuData(tCMDNode* dHead, int length){    int i;    for (i = 0; i < length; i++)    {        tCMDNode* pCMDNode = &dHead[i];        MenuConfig(pCMDNode->cmd, pCMDNode->desc, pCMDNode->handler);    }    return 0;}int main(int argc, char* argv[]){    InitMenuData(dHead, numOfCmdExHelp);    ExecuteMenu();    return 0;}int help(int argc, char* argv[]){    printf("+--------+---------------------------------+\n");    printf("+ help   + cmd tips                        +\n");    printf("+ quit   + exit cmd                        +\n");    printf("+ version+ show version                        +\n");    printf("+ upper  + change the case into uppercase Letters +\n");    printf("+ lower  + change the case into lowercase Letters +\n");    printf("+ sub    + subtraction of two numbers           +\n");    printf("+ add    + addition of two numbers         +\n");    printf("+ multi  + multiplication of two numbers   +\n");        printf("+--------+---------------------------------+\n");    return 0;}int quit(int argc, char* argv[]){    exit(0);    return 0;}int upper(int argc, char* argv[]){    int i;    char arr[100];    printf("please input contents:");    scanf("%s", arr);    for(i=0; arr[i]!='\0'; i++)    {        if(arr[i]>='A'&&arr[i]<='Z')            arr[i]+=32;    }    printf("%s\n", arr);    return 0;}int lower(int argc, char* argv[]){    int i;    char arr[100];    printf("please input contents:");    scanf("%s", arr);    for(i=0; arr[i]!='\0'; i++)    {        if(arr[i]>='a'&&arr[i]<='z')            arr[i]-=32;    }    printf("%s\n", arr);    return 0;}int version(int argc, char* argv[]){    printf("the version is 1.0.0\n");    return 0;}int add(int argc, char* argv[]){    double num1,num2,count;    printf("+-------*--------*--------*--------*-------+\n");    printf("please input two numbers:");    scanf("%lf %lf",&num1, &num2);    char a;    count = num1 + num2;    a = '+';    printf("%lf  %c %lf = %lf \n",num1, a, num2, count);    return 0;}int sub(int argc, char* argv[]){    double num1,num2,count;    printf("+-------*--------*--------*--------*-------+\n");    printf("please input two numbers:");    scanf("%lf %lf",&num1, &num2);    char a;    count = num1 - num2;    a = '-';    printf("%lf  %c %lf = %lf \n",num1, a, num2, count);    return 0;}int multi(int argc, char* argv[]){    double num1,num2,count;    printf("+-------*--------*--------*--------*-------+\n");    printf("please input two numbers:");    scanf("%lf %lf",&num1, &num2);    char a;    count = num1 * num2;    a = '*';    printf("%lf  %c %lf = %lf \n",num1, a, num2, count);    return 0;}CC_PTHREAD_FLAGS= -lpthreadCC_FLAGS= -cCC_OUTPUT_FLAGS= -oCC= gccRM= rmRM_FLAGS= -fTARGET= testOBJS= linktable.o menu.o test.oall:$(OBJS)$(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS).c.o:$(CC) $(CC_FLAGS) $


3实验结果


实现的命令8个:

help帮助

version版本号 

quit退出

upper将字符串中大写字母变小写

lower将字符串中小写字母变大写

add

sub

mult 分别计算两个数的加减乘


4.提交代码到版本库


. 实验总结

1. getopt()用来获取命令行参数。参数argc和argv[]是由main()传递的参数个数和参数内容。参数optstring 则代表欲处理的选项字符串。此函数会返回在argv[] 中下一个的选项字母,此字母会对应参数optstring 中的字母。

2.当项目中文件数目较多时,每次都使用gcc -o 编译很不方便。这时,使用Makefile文件配置编译过程。例如:在Makefile中加入以下命令all: linktable.c test.c menu.c menu,则每次执行make就相当于执行gcc -o linktable.c menu.c test.c,会编译并生成生成可执行文件menu。这种方法极大的简化了编译。并且,为了提高make脚本在不同项目中的通用性,应该使用各种宏代替其中的GCC命令。

3.将menu.c从主函数中独立出来后,会极大的降低menu.c和其它文件的耦合程度,这样如果要给menu项目增加新的功能,只需要修改menu.c文件及menu.h中的相应接口,这使得menu程序的升级和维护比较容易。



原创粉丝点击