源程序
lxn.h
#ifndef LXN_H_INCLUDED
#define LXN_H_INCLUDED
# define N_SIZE 25 //姓名字节最大长度
# define P_SIZE 20 //电话字节最大长度
# define A_SIZE 50 //地址字节最大长度
# define E_SIZE 30 //邮箱字节最大长度
# define Q_SIZE 20 //QQ字节最大长度
typedef struct Contact
{
char name[N_SIZE];
char phone[P_SIZE];
char address[A_SIZE];
char email[E_SIZE];
char QQ[Q_SIZE];
struct Contact * pNext;
} CONTACT, * PCONTACT;
//函数的声明
int menu_select ();
PCONTACT creat_list ();
void traverse_list (PCONTACT pHead); //显示记录
bool insert_list (PCONTACT pHead, int pos);//输入记录
int length_list (PCONTACT pHead); //求有效节点的个数
void sort_list (PCONTACT pHead); //通讯录进行排序
void search_list (PCONTACT pHead); //查找
void delete_list (PCONTACT pHead, int pos);//删除节点
void delete_name (PCONTACT pHead); //删除
void save_list (PCONTACT pHead); //保存
#endif // LXN_H_INCLUDED
lxn.cpp
# include <stdio.h>
# include <string.h> //提供字符串处理的原函数
# include <stdlib.h> //提供malloc,system,exit等函数
# include "lxn.h"
/*********************************************************
* 功能描述: 功能选择面板
* 输入参数: s-功能号码
* 输出参数: 无
* 返回值: num
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
int menu_select () //功能选择面板
{
char s[20];
int num;
printf ("********************************************************************\n");
printf ("\t\t☆★☆★☆★ ~_~ ~_~ ~_~ ☆★☆★☆★\n");
printf ("\n\t\t ☆★欢迎使用Cube007制作的通讯录☆★\n");
printf ("\n\t☆★选择你需要操作的功能:☆★(现无记录,建议先增加记录)★☆\n");
printf ("\t\t\t1.【输入记录】\n");
printf ("\t\t\t2.【显示记录】\n");
printf ("\t\t\t3.【以名字查询所需的信息】\n");
printf ("\t\t\t4.【删除记录】\n");
printf ("\t\t\t5.【保存通讯录】\n");
printf ("\t\t\t6.【退出不保存!!】\n");
printf ("\n");
printf ("\t☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★");
printf ("\n\n********************************************************************\n\n");
do
{
printf ("选择你需要操作的功能号码(1~6):");
gets (s);
num = atoi(s); //将字符串转换成一个整数值, 要头文件stdlib.h
//scanf("%d",&num);
}
while (num < 1 || num > 6);
return num;
}
/*********************************************************
* 功能描述: 创建一个动态空链表
* 输入参数: 无
* 输出参数: 无
* 返回值: pHead
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
PCONTACT creat_list ()
{
//分配了一个不存放有效数据的头结点
PCONTACT pHead = (PCONTACT)malloc( sizeof(CONTACT) );
/*if (NULL == pHead)
{
exit (-1); //分配内存失败,终止程序
}*/
pHead->pNext = NULL;
return pHead;
}
/*********************************************************
* 功能描述: 在pHead所指向链表的第pos个节点的前面插入一个新的结点
* 输入参数: name,phone,address,email,QQ
* 输出参数: 无
* 返回值: true
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
bool insert_list (PCONTACT pHead, int pos)
{
int i = 0;
PCONTACT p = pHead;
while (NULL != p && i < pos-1)
{
p = p->pNext;
++i;
}
if (i > pos-1 || NULL == p)
return false;
//如果程序能执行到这一行说明p已经指向了第pos-1个结点,但第pos-1个节点是否存在无所谓
//分配新的结点
PCONTACT pNew = (PCONTACT)malloc(sizeof(CONTACT));
if (NULL == pNew)
{
// printf("动态分配内存失败!\n");
exit(-1);
}
system ("CLS");
printf ("\n\n***********************************************************\n");
printf ("\t\t你能在此目录下创建并添加联系人信息");
printf ("\n***********************************************************\n");
printf ("请输入联系人姓名:");
gets (pNew->name);
printf("请输入联系人电话号码:");
gets (pNew->phone);
printf ("请输入联系人地址:");
gets (pNew->address);
printf ("请输入联系人邮箱:");
gets (pNew->email);
printf ("请输入联系人QQ:");
gets (pNew->QQ);
printf ("恭喜你!!成功添加了联系人信息!!");
printf ("\n************************************************************\n");
printf ("\n\n");
//将新的结点存入p节点的后面
PCONTACT q = p->pNext;
p->pNext = pNew;
pNew->pNext = q;
return true;
}
/*********************************************************
* 功能描述: 遍历通讯录的信息,先排序,再输出
* 输入参数: 无
* 输出参数: 无
* 返回值: 0
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
void traverse_list (PCONTACT pHead)
{
//对通讯录进行排序,按姓名的拼音顺序
sort_list (pHead);
int len = length_list (pHead);
PCONTACT p = pHead->pNext;
int i;
system ("CLS");//调用DOS命令CLS能够清屏
printf ("*************************************************************\n");
printf ("==================== → 用户信息记录表 ← ===================\n");
printf ("*************************************************************\n");
if (p != NULL)
{
for (i = 0; i < len; ++i, p = p->pNext)
{
printf ("联系人姓名:%s\n", p->name);
printf ("联系人电话号码:%s\n", p->phone);
printf ("联系人地址:%s\n", p->address);
printf ("联系人邮箱:%s\n", p->email);
printf ("联系人QQ:%s\n", p->QQ);
printf ("********************************************************\n");
if (i + 1 < len)
{
printf ("\n\t\t__________________________");
system ("pause"); // 在命令行上输出一行 请按任意键继续. . . 的字,等待用户按一个键,然后返回。
}
}
}
else
{
printf ("对不起!!没有任何人的记录!!\n\n");
printf ("=============================================================\n");
}
return;
}
/*********************************************************
* 功能描述: 求有效节点的个数
* 输入参数: 无
* 输出参数: 无
* 返回值: len
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
int length_list (PCONTACT pHead)
{
PCONTACT p = pHead->pNext;
int len = 0;
while (NULL != p)
{
++len;
p = p->pNext;
}
return len;
}
/*********************************************************
* 功能描述: 对通讯录进行排序,按姓名的拼音顺序
* 输入参数: 无
* 输出参数: 无
* 返回值: 0
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
void sort_list (PCONTACT pHead)
{
int i, j;
int len = length_list (pHead);
char name[N_SIZE];
char phone[P_SIZE];
char address[A_SIZE];
char email[E_SIZE];
char QQ[Q_SIZE];
PCONTACT p, q;
//冒泡排序
for (i = 0, p = pHead->pNext; i < len - 1; ++i, p = p->pNext)
for (j = i + 1, q = p->pNext; j < len; ++j, q = q->pNext)
if (strcmp (p->name, q->name) > 0)
{
//交换姓名
strcpy (name, p->name);
strcpy (p->name, q->name);
strcpy (q->name, name);
//交换电话
strcpy (phone, p->phone);
strcpy (p->phone, q->phone);
strcpy (q->phone, phone);
//交换地址
strcpy (address, p->address);
strcpy (p->address, q->address);
strcpy (q->address, address);
//交换邮箱
strcpy (email, p->email);
strcpy (p->email, q->email);
strcpy (q->email, email);
//交换QQ
strcpy (QQ, p->QQ);
strcpy (p->QQ, q->QQ);
strcpy (q->QQ, QQ);
}
return;
}
/*********************************************************
* 功能描述: 对通讯录进行查找
* 输入参数: name
* 输出参数: name,phone,address,email,QQ
* 返回值: 0
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
void search_list (PCONTACT pHead)
{
PCONTACT p = pHead->pNext;
char name[N_SIZE];
int len = length_list (pHead); //记录容量的最大值
int i;
int mark = 0;
int a = 0;
system ("CLS");
printf ("\n**************************************************************\n");
printf ("================ → 用户信息查询功能 ← ==================\n");
printf ("**************************************************************\n");
printf ("输入要查找联系人的姓名:");
gets (name);
if (NULL != p)
{
for (i = a; i < len; ++i, p = p->pNext)
{
if (strcmp (name, p->name) == 0)
{
printf ("*************************以下是您查找的用户信息******************\n");
printf ("联系人姓名:%s\n", p->name);
printf ("联系人电话号码:%s\n", p->phone);
printf ("联系人地址:%s\n", p->address);
printf ("联系人邮箱:%s\n", p->email);
printf ("联系人QQ:%s\n", p->QQ);
printf ("********************************************************\n");
++mark;
if (i + 1 < len)
{
printf ("\n\t\t__________________________");
system ("pause"); // 在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。
}
}
}
if (0 == mark)
{
printf ("对不起!!没有此人的记录!!\n\n");
printf ("=============================================================\n");
}
}
else
{
printf ("对不起!!没有任何人的记录!!\n\n");
printf ("=============================================================\n");
}
return;
}
/*********************************************************
* 功能描述: 删除用户记录
* 输入参数: name
* 输出参数: 无
* 返回值: 0
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
void delete_name (PCONTACT pHead)
{
int i, pos;
int mark = 0;
int val;
int len = length_list (pHead); //记录容量的最大值
char name[N_SIZE];
PCONTACT p = pHead->pNext;
system ("CLS");
printf ("\n**************************************************************\n");
printf ("================ → 用户信息删除功能 ← ==================\n");
printf ("**************************************************************\n");
printf ("输入要删除联系人的姓名:");
gets (name);
if (NULL != p)
{
for (i = 1; i <= len; ++i, p = p->pNext)
{
if (strcmp (name, p->name) == 0)
{
printf ("*************************以下是您要删除的用户信息******************\n");
printf ("num:%d\n", mark+1);
printf ("联系人姓名:%s\n", p->name);
printf ("联系人电话号码:%s\n", p->phone);
printf ("联系人地址:%s\n", p->address);
printf ("联系人邮箱:%s\n", p->email);
printf ("联系人QQ:%s\n", p->QQ);
printf ("********************************************************\n");
pos = i;
++mark;
}
}
if (1 == mark )
{
printf ("\n\t\t是否确定删除?(y/n)");
if (getchar () =='y' || getchar () =='Y')
{
delete_list (pHead, pos); //删除节点
printf ("\n\t\t删除成功!\n");
printf ("\n\t\t__________________________");
system ("pause"); // 在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。
}
else
{
printf (" ");
getchar ();
return;
}
}
else if (mark > 1)
{
printf ("这里有%d个相同的用户!\n", mark);
printf ("您想删除第几个用户的记录!\n");
printf ("num:");
scanf ("%d", &val);
pos = pos - mark + val;
delete_list (pHead, pos); //删除节点
printf ("\n\t\t删除成功!\n");
printf ("\n\t\t__________________________");
system ("pause"); // 在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。
}
else
{
printf ("对不起!!没有此人的记录!!\n\n");
printf ("=============================================================\n");
}
}
else
{
printf ("对不起!!没有任何人的记录!!\n\n");
printf ("=============================================================\n");
}
return;
}
/*********************************************************
* 功能描述: 删除在pHead所指向链表的第pos个节点
* 输入参数:
* 输出参数:
* 返回值: 0
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
void delete_list (PCONTACT pHead, int pos)
{
int i = 0;
PCONTACT p = pHead;
if (NULL == p->pNext)
{
printf ("对不起!!没有任何人的记录!!\n\n");
printf ("=============================================================\n");
return;
}
while (NULL != p->pNext && i < pos - 1)
{
p = p->pNext;
++i;
}
//如果程序能执行到这一行说明p已经指向了第pos个结点,并且第pos个节点是存在的
PCONTACT q = p->pNext; //q指向待删除的结点
p->pNext = p->pNext->pNext; //删除p节点后面的结点
free (q); //释放q所指向的节点所占的内存
q = NULL;
return;
}
/*********************************************************
* 功能描述: 通讯录的记录存盘操作,使用文件指针
* 输入参数:
* 输出参数:
* 返回值: 0
* 其它说明: 消息字段之间用分号(;)分隔
**********************************************************/
void save_list (PCONTACT pHead)
{
FILE * fp;
PCONTACT p = pHead->pNext;
fp = fopen ("contact.txt", "w");
fprintf (fp, "=============== → 用户信息记录表 ← =================\n");
while (NULL != p)
{
fprintf (fp, "====================================================\n");
fprintf (fp, "联系人姓名:%s\n", p->name);
fprintf (fp, "联系人电话号码:%s\n", p->phone);
fprintf (fp, "联系人地址:%s\n", p->address);
fprintf (fp, "联系人邮箱:%s\n", p->email);
fprintf (fp, "联系人QQ:%s\n", p->QQ);
p = p->pNext;
}
fprintf (fp, "*************************************************************\n");
fclose (fp);
printf ("\n\n恭喜你!!成功储存,你能在contact.txt找到相应纪录\n");
printf ("**************************************************************\n");
return;
}
main.cpp
/**********************************************************
* 版权所有 (C)2015, Liu Xiaonan
*
* 文件名称: lxn.cpp lxn.h main.cpp
* 文件标识: 无
* 内容摘要: 通讯录是人们日常生活中经常要用到的通讯管理工具, 它以文件的方式保存用户录入的数据, 并提供查询的功能供用户查询和使用通讯录信息。
* 其它说明: 无
* 当前版本: V1.0
* 作 者: 刘小楠
* 完成日期: 20151229
*
* 修改记录: 无
* 修改日期: 无
* 版本号: 无
* 修改人: 无
* 修改内容: 无
**********************************************************/
// 通讯录,主要用动态链表实现
# include <stdio.h>
# include <string.h> //提供字符串处理的原函数
# include <stdlib.h> //提供malloc,system,exit等函数
# include "lxn.h"
int main ()
{
PCONTACT pHead = NULL;
int num; //功能选择需要的号码
system ("cls"); /* 清屏,需要头文件stdlib.h */
system ("color 1f"); // C语言中调用dos函数颜色
system ("cls"); //调用DOS命令CLS能够清屏
pHead = creat_list ();
while (1)
{
int i = 0;
switch (menu_select ())
{
case 1:
insert_list (pHead, ++i); //输入记录
break;
case 2:
traverse_list (pHead); //显示记录
break;
case 3:
search_list (pHead); //查找
break;
case 4:
delete_name (pHead); //删除
break;
case 5:
save_list (pHead); //保存
break;
case 6:
exit (0); //返回
break;
default:
printf ("请输入数字1到6:\n");
}
printf ("\t◇◆请按ENTER返回功能操作菜单◇◆\n");
getchar ();
system ("CLS");
}
return 0;
}
运行结果: