频道栏目
首页 > 程序开发 > 软件开发 > C语言 > 正文
软件工程:C编码实践篇学习总结
2017-10-10 14:17:00      个评论    来源:lbq19950117的博客  
收藏   我要投稿

实验四:用可重用的链表模块来实现命令行菜单小程序V2.5

实验要求

用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作; 链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变; 可以将通用的Linktable模块集成到我们的menu程序中;
接口规范;

实验过程

1.建立远程仓库,并下载到本地

git clone https://github.com/libaoquan95/seClass_lab4.git

并进入版本库并创建 menu.c linktable.h linktable.c 文件
这里写图片描述

2 linktable.h

#ifndef _LINK_TABLE_H_
#define _LINK_TABLE_H_

#include 
#define  SUCCESS 0
#define  FAILURE (-1)

/*
 * LinkTableNode Node Type
 */
typedef struct LinkTableNode
{
    struct LinkTableNode *pNext;
}tLinkTableNode;

/*
 * LinkTableNode Type
 */
typedef struct LinkTable
{
    tLinkTableNode * pHead;
    tLinkTableNode * pTail;
    int              SumOfNode;
}tLinkTable;

tLinkTable * CreateLinkTable();
int          DelLinkTable(tLinkTable* pLinkTable);
int          AddLinkTable(tLinkTable* pLinkTable,tLinkTableNode *pNode);
int          DelLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode);
tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable);
tLinkTableNode * GetNextLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode);
#endif

3 linktable.c

#include 
#include 
#include 
#include "linktable.h"

tLinkTable * CreateLinkTable()
{
    tLinkTable *pLinkTable=(tLinkTable*)malloc(sizeof(tLinkTable));
    if (pLinkTable == NULL)
    {
        return NULL;
        printf("create linktable failure! ");
    }
    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    return pLinkTable;
}

int DelLinkTable(tLinkTable* pLinkTable)
{
    if(pLinkTable == NULL)
    {
        return FAILURE;
    }

    while(pLinkTable->pHead != NULL)
    {
        tLinkTableNode *p = pLinkTable->pHead;
        pLinkTable->pHead = p->pNext;
        free(p);
    }

    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    free(pLinkTable);
    return SUCCESS;
}

int AddLinkTable(tLinkTable* pLinkTable,tLinkTableNode *pNode)
{ 
    if(pLinkTable == NULL || pNode == NULL)
    {
        return FAILURE;
    }
    if(pLinkTable->pHead == NULL && pLinkTable->pTail == NULL)
    {
        pLinkTable->pHead = pNode;
        pLinkTable->pTail = pNode;
        pLinkTable->pTail = NULL;
        pLinkTable->SumOfNode = 1;
    }
    else
    {
        pLinkTable->pTail->pNext = pNode;
        pLinkTable->pTail = pNode;
        pLinkTable->pTail->pNext = NULL;
        pLinkTable->SumOfNode ++;
    }
    return SUCCESS;
}

int DelLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode)
{
    if (pLinkTable == NULL)
    {
        return FAILURE;
    }
    tLinkTableNode *pWork = pLinkTable->pHead;
    tLinkTableNode *pre = pWork;

    if (pLinkTable->pHead == pNode)
    {
        pLinkTable->pHead = pWork->pNext;
        free(pWork);
        return SUCCESS;
    }

    while (pWork != NULL)
    {
        if(pWork == pNode)
        {
            pre->pNext = pWork->pNext;
            free(pWork);
            return SUCCESS;
        }
        pre = pWork;
        pWork = pWork->pNext;
    }

    return FAILURE;
}

tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable)
{
    if (pLinkTable->pHead == NULL)
    {
        printf("LinkTable is empty\n");
        return NULL;
    }
    return pLinkTable->pHead;
}

tLinkTableNode * GetNextLinkTableNode(tLinkTable* pLinkTable,tLinkTableNode *pNode)
{
    if (pLinkTable == NULL || pNode == NULL)
    {
        printf("LinkTable is empty\n");
        return NULL;
    }

    tLinkTableNode *pWork = pLinkTable->pHead;

    while(pWork != NULL)
    {
        if(pWork == pNode)
            return pWork->pNext;
        pWork = pWork->pNext;
    }

    return NULL;
}

4 menu.c

/*
 * Copyright (C) libaoquan95@github.com, 2017-2018
 *
 * File name                  : menu.c
 * Principal author           : libaoquan95
 * Subsystem name             : menu 
 * Module name                : menu
 * Language                   : C 
 * Date of first release      : 2017/10/09
 * Deacription                : This is a menu program
*/

#include 
#include 
#include 
#include 
#include 
#include "linktable.h"

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

int PrintCommand();
int PrintSystemTime();
int PrintCurrentWorkingDirectory();
int Add();
int Sub();
int Mul();
int Div();
int Quit();

typedef struct DataNode
{
    tLinkTableNode * pNext;
    char* cmd;
    char* desc;
    int (*handler)();
}tDataNode;

tDataNode * FindCmd(tLinkTable *head, char *cmd)
{
    tDataNode *pNode = (tDataNode*)GetLinkTableHead(head);
    while(pNode != NULL)
    {
        if(strcmp(pNode->cmd, cmd) == 0)
        {
            return pNode;
        }
        pNode = (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)pNode);
    }
    return NULL;
}

int ShowAllCmd(tLinkTable *head)
{
    tDataNode *pNode = (tDataNode*)GetLinkTableHead(head);
    printf("-------------------------------------------------------------------\n");
    while(pNode != NULL)
    {
        printf("\t\t %s: \t\t %s\n", pNode->cmd, pNode->desc);
        pNode= (tDataNode*)GetNextLinkTableNode(head, (tLinkTableNode*)pNode);
    }
    printf("-------------------------------------------------------------------\n");
    return 0;
}

static tDataNode menu[] =
{
    {(tLinkTableNode*)&menu[1], "help", "Print all command of menu",                  PrintCommand},
    {(tLinkTableNode*)&menu[2], "time", "Show system time",                           PrintSystemTime},
    {(tLinkTableNode*)&menu[3], "pwd", "Show current working directory",              PrintCurrentWorkingDirectory},
    {(tLinkTableNode*)&menu[4], "add", "Calculate the summarize of the two integer numbers",      Add},
    {(tLinkTableNode*)&menu[5], "sub", "Calculate the subtractions of the two integer numbers",   Sub},
    {(tLinkTableNode*)&menu[6], "mul", "Calculate the multiplication of the two integer numbers", Mul},
    {(tLinkTableNode*)&menu[7], "p", "Calculate the pision of the two integer numbers",       Div},
    {(tLinkTableNode*)NULL,     "quit", "Exit menu program",                         Quit}
};

int InitMenuData(tLinkTable **ppLinkTable)
{
    *ppLinkTable = CreateLinkTable();
    (*ppLinkTable)->pHead = (tLinkTableNode*)&menu[0];
    (*ppLinkTable)->pTail = (tLinkTableNode*)&menu[7];
    (*ppLinkTable)->SumOfNode = 8;
}

tLinkTable *head = NULL;

int main()
{
    InitMenuData(&head);
    while(1)
    {
        char cmd[CMD_MAX_LEN];
        printf("$menu > ");
        scanf("%s", cmd);
        tDataNode *p = FindCmd(head, cmd);
        if(p == NULL)
        {
            printf("ERROR: This is not a command, you can input 'help' to find command\n");
            continue;
        }
        if(p->handler != NULL)
        {
            p->handler();
        }
    }
}

/**
 * print all command and it's information
 * @param none
 * @return none
 */
int PrintCommand()
{
    ShowAllCmd(head);
    return 0;
}

/**
 * print current time
 * @param none
 * @return none
 */
int PrintSystemTime()
{
    struct tm *ptr;
    time_t it;
    it = time(NULL);
    ptr = localtime(&it);
    printf("%4d年%02d月%02d日  %d:%d:%d\n", ptr->tm_year + 1900, ptr->tm_mon + 1, ptr->tm_mday, 
                                          ptr->tm_hour, ptr->tm_min,ptr->tm_sec);
    return 0;
}

/**
 * print current working directory path
 * @param none
 * @return none
 */
int PrintCurrentWorkingDirectory()
{
    char buf[256];
    getcwd(buf, sizeof(buf));
    printf("当前路径:  %s\n", buf);
    return 0;
}

/**
 * calculate add of two interage numbers
 * @param none
 * @return calculate result
 */
 int Add()
 {
     int num1 = 0, num2 = 0;
     printf("input number1:");
     scanf("%d", &num1);
     printf("input number2:");
     scanf("%d", &num2);
     printf("%d + %d = %d\n", num1, num2, num1 + num2);
     return 0;
 }

 /**
  * calculate sub of two interage numbers
  * @param none
  * @return calculate result
  */
 int Sub()
 {
     int num1 = 0, num2 = 0;
     printf("input number1:");
     scanf("%d", &num1);
     printf("input number2:");
     scanf("%d", &num2);
     printf("%d - %d = %d\n", num1, num2, num1 - num2);
     return 0;
 }

 /**
  * calculate mul of two interage numbers
  * @param none
  * @return calculate result
  */
 int Mul()
 {
     int num1 = 0, num2 = 0;
     printf("input number1:");
     scanf("%d", &num1);
     printf("input number2:");
     scanf("%d", &num2);
     printf("%d * %d = %d\n", num1, num2, num1 * num2);
     return 0;
 }

 /**
  * calculate p of two interage numbers
  * @param none
  * @return calculate result
  */
 int Div()
 {

     int num1 = 0, num2 = 0;
     printf("input number1:");
     scanf("%d", &num1);
     printf("input number2:");
     scanf("%d", &num2);
     if(num2 != 0)
     {
         printf("%d / %d = %d\n", num1, num2, num1 / num2);
     }
     else
     {
         printf("ERROR: don't pision 0\n");
     }
     return 0;
 }

 /**
  * quit command
  * @param none
  * @return none
  */
 int Quit()
 {
     exit(0);
     return 0;
 }

5.编译程序并运行
5.1 编译

gcc linktable.h linktable.c menu.c -o menu
./menu

这里写图片描述
5.2 运行
help 命令
这里写图片描述
time 命令
这里写图片描述
pwd 命令
这里写图片描述
add 命令
这里写图片描述
sub 命令
这里写图片描述
mul 命令
这里写图片描述
p 命令
这里写图片描述
错误的命令
这里写图片描述
quit 命令
这里写图片描述
6.上传至远程版本库
这里写图片描述


实验总结

通过这次菜单程序模块化设计使我学会了许多的软件工程思想,体会到了模块化的巨大作用

本次实验设计了一个通用的链表模块,在调用时指定了具体的数据类型,体现了高类聚低耦合的思想,接口更加规范,使我们的代码更具有通用性并且更容易管理。

在实验中体会到了函数接口规范对于可重用的重要性,以及代码设计规范的一些方法。在编译的过程中也学习了链接的相关知识,对gcc编译器有了进一步的理解.

点击复制链接 与好友分享!回本站首页
上一篇:c语言经典题之杨辉三角形
下一篇:C语言面试练习题,请编写函数
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站