项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」

项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」项目实战:C/C++版本“cmd命令”操作通讯录(作为数据结构双向链表面向接口编程练习推荐)目录项目实战:C/C++版本写一个能够运行命令,的双向链表系统1.编译环境:Win10专业版x64VS20152.运行结果如下

项目实战:C/C++版本  “cmd 命令” 操作通讯录
 (作为数据结构 双向链表 面向接口编程 练习 推荐)

 

目录

项目实战:C/C++版本 写一个能够运行命令,的双向链表系统 

1.编译环境:Win10专业版x64    VS2015

2.运行结果如下:

3.主要源码:


==================================================================

1.编译环境:Win10专业版x64    VS2015

==================================================================

项目简介:运用C/C++语言,写了一个cmd名称的程序。其中演示效果如下,当你在该界面输入指定的下面的命令(就像是在cmd里面运行一样,完全一样的操作习惯),该系统就会对指定的命令做不同的行为解释(执行不同的操作)。且其中有比较好的代码健壮性和可以可扩展性。你在其中添加新的命令,只需要创建新的功能函数就可以。而不需要破坏其中的代码架构和封装。这一点你看源码就知道。这个项目我想称之为,命令行模式的双向链表更加合适。也算对数据结构的命令行模式的一个应用。

该项目基于控制台操作,实现了输入指定命令,就可以对通讯录实现,增加,修改,删除,查询,显示,帮助等功能的实现。其中使用手写双向链表存储数据,和规范化的接口来编程实现功能。其中只有你写了,你才会发现前面加粗的含义,对于C和数据结构的提升有着绝对的好处。对于初学者推荐:推荐30min内写完。

说明:这一整套 “cmd命令” 操作通讯录 ,你就会对于8大设计原则最后一条有所理解。其他几条也有所理解。

==================================================================

2.运行结果如下:

项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」

项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」

项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」

项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」

 

==================================================================

源码: (带详细注释的) 链接:https://pan.baidu.com/s/1pM76M3x 密码:2826

可执行的exe文件:链接:https://pan.baidu.com/s/1i6fsILB 密码:2xlq

3.主要源码:

Cmd.h

#pragma once

//12:30
typedef void (*pfun)();

struct CMD_MAP
{
	char *m_szcmd;
	pfun m_pfun;
	
};

void Create();
void Add();
void Insert();
void Delete();
void Clearn();
void Modify();
void Find();
void Show();
void Help();
void Exit();

void Finally();

 

 

 

 

 

Cmd.cpp

#include "stdafx.h"
#include "Cmd.h"
#include "Linker.h"

void Create()
{
	MyCreateList();
}

void Add()
{
	MyAddNode();
}

void Insert()
{
	MyInsertNode();
}

void Delete()
{
	MyDeleteNode();
}

void Clearn()
{
	MyClearnList();
}

void Modify()
{
	MyModifyNode();
}

void Find()
{
	MyShowNode();
}


void Show()
{
	MyShowList();
}

void Help()
{
	MyHelp();
}

void Exit()
{
	exit(0);
}

CMD_MAP g_Cmd_Map[] = {
	{"Create", Create},
	{"Add", Add},
	{"Insert", Insert},
	{"Delete", Delete},
	{"Clearn", Clearn},
	{"Modify", Modify},
	{"Find", Find},
	{"Show", Show},
	{"Help", Help},
	{"Exit", Exit},
	{"NULL", NULL}
};

void Finally()
{
	system("title 双向链表 2018.1.19");
	system("color 0e");

	Help();  //提示操作,避免一开始都不知道应该怎么输入

	char szCmdBuf[20] = "";
	CMD_MAP *pCmdMap = NULL;

	while (true)
	{
		
		pCmdMap = g_Cmd_Map;
		cout << endl << "请输入命令:";
		cin >> szCmdBuf;

		while (true)
		{
			system("cls");
			if (0 == strcmp(szCmdBuf, pCmdMap->m_szcmd))
			{
				pCmdMap->m_pfun();
				break;
			}

			if ("NULL" == pCmdMap->m_szcmd)
			{
				cout << "您输入的命令有误,请从新输入!" << endl;
				break;
			}

			pCmdMap++;
		}
	}
}

 

Linker.h

#pragma once

struct NODE
{
	char m_szName[20];
	int  m_Age;
	char m_szSex[4];
	char m_szAddr[100];
	char m_szTel[20];

	NODE *m_pNext;
	NODE *m_pFront;
};
//写完之后记得把Struct拆成Data+Linker的形式


void MyInputNode(NODE& pt);  //输入一个刚创建好的空白节点
void MyOutputNode(NODE& pt);  //输出已经存在的节点
void MyCreateList();   
NODE& MyAdd_Node();  //单独只是创建一个节点
NODE* MyAddNode();   //在链表尾部添加一个节点
void MyShowList();   
void MyShowNode();   //等价于 MyFindNode()+MyShowNode()
NODE& MyFindNode(char *FindName);
void MyInsertFront(char* ptName, NODE* pResFindNode, NODE* pNew); //前插(插在查询到的节点之前)
void MyInsertNext(char* ptName, NODE* pResFindNode, NODE* pNew);  //后插(插在查询到的节点之后)
void MyInsertNode();
void MyModifyNode();
void MyDeleteNode();
void MyClearnList();
void MyHelp();

Linker.cpp

#include "stdafx.h"
#include "Linker.h"

NODE *g_pHead = NULL;
NODE *g_pEnd = NULL;

void MyInputNode(NODE& pt)  //输入一个刚创建好的空白节点
{
	pt.m_pFront = NULL;
	pt.m_pNext = NULL;
	cout << "姓名:";      cin >> pt.m_szName;
	cout << "年龄:";      cin >> pt.m_Age;
	cout << "性别:";      cin >> pt.m_szSex;
	cout << "联系方式:";   cin >> pt.m_szTel;
	cout << "住址:";      cin >> pt.m_szAddr;
}

void MyOutputNode(NODE& pt)  //输出已有的节点
{
	cout << "姓名:" << pt.m_szName << endl;
	cout << "年龄:" << pt.m_Age << endl;
	cout << "性别:" << pt.m_szSex << endl;
	cout << "联系方式:" << pt.m_szTel << endl;
	cout << "住址:" << pt.m_szAddr << endl << endl;
}
void MyCreateList()
{
	NODE *pTemp = new NODE;

	if (NULL == pTemp)
	{
		cout << "创建链表失败!" << endl;
	}
	else
	{
		MyInputNode(*pTemp);
		cout << "创建链表成功!" << endl << endl;
	}

	g_pHead = pTemp;
	g_pEnd = pTemp;
}

//单独只是创建一个节点
NODE& MyAdd_Node()
{
	NODE* pTemp = new NODE;

	if (NULL != pTemp)
	{
		MyInputNode(*pTemp);
	}

	return *pTemp;
}

//在链表尾部添加一个节点
NODE* MyAddNode()
{
	if (NULL == g_pHead || NULL == g_pEnd)
	{
		cout << "该链表不存在,请从新创建链表再进行该项操作!" << endl;
	}

	NODE* pNew = &MyAdd_Node();  //引用的使用
	g_pEnd->m_pNext = pNew;
	pNew->m_pFront = g_pEnd;
	g_pEnd = pNew;
	return NULL;
}

void MyShowList()
{
	int nCount = 1;

	if (NULL != g_pHead && NULL != g_pEnd)
	{
		NODE* pt = g_pHead;

		cout << "------------------显示链表开始------------------" << endl;
		while (pt != NULL)
		{	
			cout << "第" << nCount << "个节点:" << endl;
			MyOutputNode(*pt);
			pt = pt->m_pNext;
			nCount++;
		}
		cout << "------------------显示链表结束------------------" << endl << endl;
	}
}

NODE& MyFindNode(char *FindName) //根据姓名查找
{
	NODE* pt = g_pHead;

	while (true)
	{
		if (NULL != pt)
		{
			if (0 == strcmp(FindName, pt->m_szName))
			{
				return *pt;
			}
			else
			{
				pt = pt->m_pNext;
			}
		}
		else
		{
			cout << "您查询的该节点不存在!" << endl << endl;
			return *pt;  //pt == NULL
		}		
	}

}

void MyShowNode()
{
	char szNameBuf[20] = "";
	cout << "请输入想要查询的姓名:";
	cin >> szNameBuf;
	MyOutputNode(MyFindNode(szNameBuf));
}

void MyInsertFront(char* ptName, NODE* pResFindNode, NODE* pNew) //前插(插在查询到的节点之前)
{
	if (pResFindNode == g_pHead)
	{
		pNew->m_pNext = g_pHead;
		g_pHead->m_pFront = pNew;
		g_pHead = pNew;
	}
	else //无论是中间还是最后一个节点,那么进行前插之后,g_pEnd的指向都不需要变化
	{
		pNew->m_pFront = pResFindNode->m_pFront;
		pNew->m_pNext = pResFindNode;
		pResFindNode->m_pFront->m_pNext = pNew;
		pResFindNode->m_pFront = pNew;	
	}
}

void MyInsertNext(char* ptName, NODE* pResFindNode, NODE* pNew)  //后插(插在查询到的节点之后)
{
	if (pResFindNode == g_pEnd)
	{
		pResFindNode->m_pNext = pNew;
		pNew->m_pFront = pResFindNode;
		g_pEnd = pNew;
	}
	else //无论是中间还是第一个节点,那么进行后之后,g_pHead的指向都不需要变化
	{
		pNew->m_pNext = pResFindNode->m_pNext;
		pNew->m_pFront = pResFindNode;
		pResFindNode->m_pNext->m_pFront = pNew;
		pResFindNode->m_pNext = pNew;
	}
}

void MyInsertNode()
{
	char szNameBuf[20] = "";
	cout << "请输入姓名(待会将会选择插入该节点之前或者之后):";
	cin >> szNameBuf;

	cout << "-------------插入操作开始-------------" << endl;
	NODE *pNew = &MyAdd_Node();
	NODE *pResFindNode = &MyFindNode(szNameBuf);

	int nChoose = 1;
	cout << "前插还是后插:(1---前插; 2---后插)" << endl;
	cin >> nChoose;
	if (1 == nChoose)
	{
		MyInsertFront(szNameBuf, pResFindNode, pNew);
	}
	else if (2 == nChoose)
	{
		MyInsertNext(szNameBuf, pResFindNode, pNew);
	}
	else
	{
		cout << "请输入1或者2,请从新再次尝试输入!" << endl;
	}
	cout << "-------------插入操作结束-------------" << endl << endl;
}

void MyModifyNode()
{
	char szNameBuf[20] = "";
	cout << "请输入姓名(将会修改的节点信息):";
	cin >> szNameBuf;

	cout << "-------------修改操作开始-------------" << endl;
	NODE *pResFindNode = &MyFindNode(szNameBuf);
	MyInputNode(*pResFindNode);
	cout << "-------------修改操作结束-------------" << endl << endl;
}

void MyDeleteNode()
{
	char szNameBuf[20] = "";
	cout << "请输入姓名(将会删除的节点信息):";
	cin >> szNameBuf;

	cout << "-------------删除操作进行中....-------------" << endl;
	NODE *pResFindNode = &MyFindNode(szNameBuf);
	if (pResFindNode == g_pHead)
	{	
		g_pHead = pResFindNode->m_pNext;
		pResFindNode->m_pNext->m_pFront = NULL;
	}
	else if (pResFindNode == g_pEnd)
	{
		g_pEnd = pResFindNode->m_pFront;
		g_pEnd->m_pNext = NULL;
	}
	else
	{
		pResFindNode->m_pFront->m_pNext = pResFindNode->m_pNext;
	}

	delete [] pResFindNode;

	cout << "-------------删除操作结束-------------" << endl << endl;
}

void MyClearnList()
{
	NODE* pt = g_pHead;

	cout << "-------------清除链表进行中....-------------" << endl;
	while (NULL != pt)
	{
		delete [] pt;
		pt = pt->m_pNext;
	}

	g_pHead = NULL;
	g_pEnd = NULL;
	cout << "-------------清除链表结束-------------" << endl << endl;
}


void MyHelp()
{
	for (size_t i = 0; i < 80; i++)
		fputchar('=');
	cout << endl;

	void Create();
	void Add();
	void Insert();
	void Delete();
	void Clearn();
	void Modify();
	void Find();
	void Show();
	void Help();
	void Exit();
	cout << "命令            语句           操作含义" << endl;
	cout << "Create         创建         创建一个链表" << endl;
	cout << "Add            添加         在该链表结尾处添加一个新的节点" << endl;
	cout << "Insert         插入         在链表任意地方随意插入一个新节点" << endl;
	cout << "Delete         删除         在链表任意地方随意删除一个已有节点" << endl;
	cout << "Clearn         清空         清空整个链表" << endl;
	cout << "Modify         修改         在链表任意地方随意是修改一个已有节点" << endl;
	cout << "Show           显示         完整的显示该链表的所有节点的详细信息" << endl;
	cout << "Help           帮助         查看帮助说明文档" << endl;
	cout << "Exit           退出         退出,结束本程序" << endl;


	for (size_t i = 0; i < 80; i++)
		fputchar('=');

	cout << endl << endl;
}

DoubleLinkedList.cpp

 

// DoubleLinkedList.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Cmd.h"


int main()
{
	Finally();
    return 0;
}

 

==================================================================

4.单向、双向链表插入理解示意图

项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」

================================================
下载链接:C/C++版本 “cmd 命令”操作通讯录

今天的文章项目实战:C/C++版本 “cmd 命令”操作通讯录 (练习推荐★★)「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/87449.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注