软件工程(C编码实践篇) 实验四:用可重用的链表模块来实现命令行菜单小程序V2.5


一、实验要求

1.用可重用的链表模块来实现命令行菜单小程序,执行某个命令时调用一个特定的函数作为执行动作;

2.链表模块的接口设计要足够通用,命令行菜单小程序的功能保持不变;

3.可以将通用的Linktable模块集成到我们的menu程序中;

4.接口规范。

先贴出本文的gitbub地址:https://github.com/Ulov888/lab4

以及最终运行截图:


二、实验过程

在上周的基础上,本周添加了新的任务,使用可重用的链表模块来实现命令行程序,那么就从这个链表模块写起吧,分别创建linktable.c和linktable.h文件
linktable.c

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

tLinkTable* CreateLinkTable()
{
    tLinkTable* pLinkTable=(tLinkTable*)malloc(sizeof(tLinkTable));
    if(pLinkTable == NULL)
    {
        return NULL;
    }
    pLinkTable->Head=NULL;
    pLinkTable->Tail=NULL;
    pLinkTable->num=0;
    return pLinkTable;
 }

 int DelLinkTable(tLinkTable* pLinkTable)
 {
     if(pLinkTable ==NULL)
     {
         return FAILURE;
     }
     while(pLinkTable->Head != NULL)
     {
         tLinkNode* pNode = pLinkTable->Head;
         pLinkTable->Head = pLinkTable->Head->Next;
         free(pNode);
         pLinkTable->num--;
     }
     pLinkTable->Head = NULL;
     pLinkTable->Tail = NULL;
     free(pLinkTable);
     return SUCCESS;
 }

 int AddLinkNode(tLinkTable* pLinkTable, tLinkNode* pNode)
 {
     if(pLinkTable == NULL ||pNode == NULL)
     {
         return FAILURE;
     }
     pNode->Next = NULL;
     if(pLinkTable->Head == NULL)
     {
         pLinkTable->Head = pNode;
     }
     if(pLinkTable->Tail == NULL)
     {
         pLinkTable->Tail = pNode;
     }
     else
     {
         pLinkTable->Tail->Next = pNode;
         pLinkTable->Tail = pLinkTable->Tail->Next;
     }
     pLinkTable->num++;
     return SUCCESS;
 }

 int DelLinkNode(tLinkTable* pLinkTable, tLinkNode* pNode)
 {
     if(pLinkTable ==NULL || pNode == NULL)
     {
         return FAILURE;
     }
     tLinkNode* p = pLinkTable->Head;
     if(pLinkTable->Head == pNode)
     {
         pLinkTable->Head = pLinkTable->Head->Next;
         free(p);
         pLinkTable->num--;
     }
     if(pLinkTable->num ==0)
     {
         pLinkTable->Tail=NULL;
         return SUCCESS;
     }
     while(p!= NULL)
     {
         if(p->Next == pNode)
         {
             tLinkNode* q = p->Next;
             p->Next = p->Next->Next;
             free(q);
             pLinkTable->num--;
             if(pLinkTable->num == 0)
             {
                 pLinkTable->Tail = NULL;
             }
             return SUCCESS;
         }
         p = p->Next;
     }
     return FAILURE;
}

tLinkNode* GetHeadNode(tLinkTable* pLinkTable)
{
    if(pLinkTable ==NULL||pLinkTable->Head==NULL)
    {
         return NULL;
    }

    return pLinkTable->Head;
}

tLinkNode* GetTailNode(tLinkTable* pLinkTable)
{
    if(pLinkTable ==NULL||pLinkTable->Tail==NULL)
    {
        return NULL;
    }
    return pLinkTable->Tail;
}

tLinkNode* GetNextNode(tLinkTable* pLinkTable,tLinkNode *pNode)
{
    if(pLinkTable==NULL||pNode==NULL)
    {
        return NULL;
    }
    tLinkNode* p=pLinkTable->Head;
    while(p!=NULL)
    {
        if(p==pNode)
        {
            return p->Next;
        }
        p=p->Next;
    }
    return NULL;
}

linktable.h

#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
#define SUCCESS 0
#define FAILURE -1

typedef struct LinkNode
{
    struct LinkNode *Next;
}tLinkNode;

typedef struct LinkTable
{
    tLinkNode *Head;
    tLinkNode *Tail;
    int num;
}tLinkTable;

tLinkTable* CreatLinkTable();
int DelLinkTable(tLinkTable *pLinkTable);
int AddLinkNode(tLinkTable *pLinkTable,tLinkNode* pNode);
int DelLinkNode(tLinkTable *pLinkTable,tLinkNode* pNode);
tLinkNode* GetHeadNode(tLinkTable* pLinkTable);
tLinkNode* GetTailNode(tLinkTable* pLinkTable);
tLinkNode* GetNextNode(tLinkTable* pLinkTable,tLinkNode *pNode);

#endif

在上周的作业里,也要做如下修改:

对linklist.c

tDataNode * FindCmd(tLinkTable*head,char * cmd)
{
    tDataNode* p=(tDataNode*)GetHeadNode(head);
    while(p!=NULL)
    {
    if(strcmp(p->cmd,cmd)==0)
        return p;
    p=(tDataNode*)GetNextNode(head,(tLinkNode*)p);
    }
    return NULL;
}

int ShowAllCmd(tLinkTable* head)
{
    tDataNode* p=(tDataNode*)GetHeadNode(head);
    printf("Menu list:\n");
    while(p!=NULL)
    {
    printf("%s-%s\n",p->cmd,p->desc);
    p=(tDataNode*)GetNextNode(head,(tLinkNode*)p);
    }
    return 0;
}




接下来贴出main文件:

#include <string.h>
#include "linklist.h"
#include "linktable.h"

#define CMD_MAX_LEN 128

void mathDemo();
void dogBark();
void help();
void quit();

int Initmenu(tLinkTable ** pLinkTable);
tDataNode * FindCmd(tLinkTable * head,char *cmd);
int ShowAllCmd(tLinkTable* head);
tLinkTable* head=NULL;


int main()
{
    char cmd[CMD_MAX_LEN];
    Initmenu(&head);
	printf("ATTENTION: input 'help' you can get all commands!\n");
	while(1)
	{

		printf("please input a command-->");
		scanf("%s",cmd);
		tDataNode *p=FindCmd(head,cmd);
		if(p==NULL)
		{
			printf("this is a wrong cmd!\n");
			continue;
		}
		printf("command:%s  description:%s\n",p->cmd,p->desc);

		if(p->handler != NULL)
		{
			p->handler();
			printf("==================================\n");
		}
	}
	return 0;
}

int Initmenu(tLinkTable ** pLinkTable)
{
    *pLinkTable=CreateLinkTable();
    tDataNode* pNode=(tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd="help";
    pNode->desc="this is help command";
    pNode->handler=help;
    AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
    pNode=(tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd="mathDemo";
    pNode->desc="this is math command";
    pNode->handler=mathDemo;
    AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
    pNode=(tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd="quit";
    pNode->desc="This is quit cmd";
    pNode->handler=quit;
    AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
    pNode=(tDataNode*)malloc(sizeof(tDataNode));
    pNode->cmd="dogBark";
    pNode->desc="This is a dog";
    pNode->handler=dogBark;
    AddLinkNode(*pLinkTable,(tLinkNode*)pNode);
    return 0;
}


void mathDemo()
{
	printf("1 + 2 = %d\n",1+2);
}
void dogBark()
{
	printf("Ruff!,RUff!,Ruff....!\n");
}
void help()
{
	ShowAllCmd(head);
}
void quit()
{
	printf("are you sure ? Y/N\t");
	char flag;
	scanf("%s",&flag);
	if(flag=='Y'||flag == 'y'){
		exit(0);
	}
	else
	{
		return ;
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值