项目实战:C/C++版本 “cmd 命令” 操作通讯录
(作为数据结构 双向链表 面向接口编程 练习 推荐)
目录
项目实战:C/C++版本 写一个能够运行命令,的双向链表系统
==================================================================
1.编译环境:Win10专业版x64 VS2015
==================================================================
项目简介:运用C/C++语言,写了一个cmd名称的程序。其中演示效果如下,当你在该界面输入指定的下面的命令(就像是在cmd里面运行一样,完全一样的操作习惯),该系统就会对指定的命令做不同的行为解释(执行不同的操作)。且其中有比较好的代码健壮性和可以可扩展性。你在其中添加新的命令,只需要创建新的功能函数就可以。而不需要破坏其中的代码架构和封装。这一点你看源码就知道。这个项目我想称之为,命令行模式的双向链表更加合适。也算对数据结构的命令行模式的一个应用。
该项目基于控制台操作,实现了输入指定命令,就可以对通讯录实现,增加,修改,删除,查询,显示,帮助等功能的实现。其中使用手写双向链表存储数据,和规范化的接口来编程实现功能。其中只有你写了,你才会发现前面加粗的含义,对于C和数据结构的提升有着绝对的好处。对于初学者推荐:推荐30min内写完。
说明:这一整套 “cmd命令” 操作通讯录 ,你就会对于8大设计原则最后一条有所理解。其他几条也有所理解。
==================================================================
2.运行结果如下:
==================================================================
源码: (带详细注释的) 链接: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 命令”操作通讯录 (练习推荐★★)「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/87449.html