// 通讯录,主要用动态链表实现
# include
# include
# include
# 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);
int main ()
{
PCONTACT pHead = NULL;
int num; //功能选择需要的号码
system ("cls"); /* 清屏,需要头文件stdlib.h */
system ("color 2e"); // 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;
}
int menu_select () //功能选择面板
{
char s[20];
int num;
printf("********************************************************************");
printf ("\t\t\t\t☆★☆★☆★ ~_~ ~_~ ~_~ ☆★☆★☆★\n");
printf ("\n\t\t\t☆★欢迎使用TN制作的通讯录☆★");
printf ("\n\n\t☆★选择你需要操作的功能:☆★(现无记录,建议先增加记录)★☆\n");
printf ("\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):");
/*
//也可以通过这种方式
scanf ("%d", &num);
getchar ();
*/
gets (s);
num = atoi(s); //将字符串转换成一个整数值, 要头文件stdlib.h
}while (num < 1 || num > 6);
return num;
}
//创建一个动态空链表
PCONTACT creat_list ()
{
//
分配了一个不存放有效数据的头结点
PCONTACT pHead = (PCONTACT)malloc( sizeof(CONTACT) );
if (NULL == pHead)
{
exit (-1); //分配内存失败,终止程序
}
pHead->pNext = NULL;
return pHead;
}
//在pHead所指向链表的第pos个节点的前面插入一个新的结点
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;
}
//遍历通讯录的信息,先排序,再输出
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 (NULL != p)
{
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"); // 在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。
}
}
}
else
{
printf ("对不起!!没有任何人的记录!!\n\n");
printf ("=============================================================\n");
}
return;
}
//有效节点的个数
int length_lis
t (PCONTACT pHead)
{
PCONTACT p = pHead->pNext;
int len = 0;
while (NULL != p)
{
++len;
p = p->pNext;
}
return len;
}
//对通讯录进行排序,按姓名的拼音顺序
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;
}
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;
}
//删除用户记录
void delete_name (PCONTACT pHead)
{
int i, pos;
int mark = 0;
int val;
int len = length_list (pHead); //记录容量的最大值
char nam
e[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个节点
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;
}
//通
讯录的记录存盘操作,使用文件指针;
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;
}