**问题描述:**
用双链表做数据结构,编写一个通讯录管理系统。本系统应具有信息的增删改查等功能。
**基本要求及提示:**
(1) 每条信息包含姓名、性别、工作单位、电话、e-mail、邮编等项。
(2) 作为一个完整系统,应具有较强的容错性。
代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define false -0
#define true 1
typedef int bool;
//结构体定义
typedef struct {
char name[10];
char sex[10];
char work[15];
char tel[15];
char email[15];
} ElemType;
typedef struct Node {
ElemType data;
struct Node *prior;
struct Node *next;
} DNode;
typedef DNode *DLinkList;
DLinkList head;
//尾插法创建信息表
void MessageCreat() {
DNode *p, *r;
char flag = 'Y';
head = (DNode *) malloc(sizeof(DNode));
head->prior = NULL;
head->next = NULL; //链表初始化
r = head;
r->next = NULL;
while (flag == 'y' || flag == 'Y') {
//定义临时变量,接收键盘输入,判断输入字符长度是否合法。
char name[100] = {0};
char sex[100] = {0};
char work[100] = {0};
char tel[100] = {0};
char email[100] = {0};
printf("请按照姓名 性别 工作单位 电话 邮箱顺序依次输入相关信息:\n");
scanf("%s %s %s %s %s", name, sex, work, tel, email);
if (strlen(name) >= 10 || strlen(sex) >= 10 || strlen(work) >= 15 || strlen(tel) >= 15 || strlen(email) >= 15) {
printf("输入信息有误,长度不合法。请重新输入。[姓名和性别:最长9个字符,工作单位&电话&邮箱:最长14个字符]\n");
continue;
}
p = (DNode *) malloc(sizeof(DNode));
strcpy(p->data.name, name);
strcpy(p->data.sex, sex);
strcpy(p->data.work, work);
strcpy(p->data.tel, tel);
strcpy(p->data.email, email);
r->next = p; //将p节点尾插到r节点之后
p->prior = r;
r = p; //r变为尾节点
printf("继续输入吗?(y/n):");
getchar();
scanf("%c", &flag);
}
r->next = NULL;
}
/*
TODO:向双链表中添加一个成员
函数功能:将成员信息elemType添加到双链表的尾部。
参数说明:head-指向双链表头结点的指针
elemType-指向成员信息的一个指针,里面存放了成员的相关信息。
*/
void MessageAdd(DLinkList head, ElemType *elemType) {
DNode *p,*q;
q=head;
while(q->next!=NULL) q=q->next;
p=(DNode *) malloc(sizeof(DNode));
q->next=p;
p->prior=q;
strcpy(p->data.name, elemType->name);
strcpy(p->data.sex, elemType->sex);
strcpy(p->data.work, elemType->work);
strcpy(p->data.tel, elemType->tel);
strcpy(p->data.email, elemType->email);
p->next=NULL;
}
/*
TODO:从双链表中删除一个成员
函数功能:根据姓名信息,从双链表中找到这个结点,并将这个结点从双链表中删除。
参数说明:head-指向双链表头结点的指针
name-需要被删除的成员名字。
返回值说明:根据name找到结点并删除成功,则返回true。否则返回false。
注意:删除结点时,内存释放
*/
bool MessageDel(DLinkList head, char *name) {
DNode *p;
p=head;
while(strcmp(p->data.name,name)&&p->next!=NULL)
{
p=p->next;
}
if(strcmp(p->data.name,name)==0)
{
p->prior->next=p->next;
if(p->next!=NULL)
p->next->prior=p->prior;
free(p);
return true;
}
else return false;
}
/*
TODO:修改双链表中的一个成员信息
函数功能:根据姓名信息,从双链表中找到这个结点,并将这个结点的信息修改为elemType所指向的成员信息。
参数说明:head-指向双链表头结点的指针
name-需要被修改的成员名字。
elemType-使用该信息修改name所指向的结点的成员信息
返回值说明:根据name找到结点并成功修改信息,则返回true。否则返回false。
*/
bool MessageChange(DLinkList head, char *name, ElemType *elemType) {
DNode *p;
p=head;
while(strcmp(p->data.name,name)&&p->next!=NULL)p=p->next;
if(strcmp(p->data.name,name)==0)
{
strcpy(p->data.name, elemType->name);
strcpy(p->data.sex, elemType->sex);
strcpy(p->data.work, elemType->work);
strcpy(p->data.tel, elemType->tel);
strcpy(p->data.email, elemType->email);
return true;
}
else return false;
}
/*
TODO:从双链表中查找一个成员
函数功能:根据姓名信息,从双链表中找到这个结点,
参数说明:head-指向双链表头结点的指针
name-需要被修改的成员名字。
返回值说明:根据name找到对应的结点则返回true。否则返回false。
*/
bool MessageFind(DLinkList head, char *name) {
DNode *p;
p=head;
while(strcmp(p->data.name,name)&&p->next!=NULL)p=p->next;
if(strcmp(p->data.name,name)==0)return true;
else return false;
}
//信息表的打印
void Print(DLinkList head) {
DNode *p;
p = head->next;
int i = 0;
while (p) //从p节点开始,依次输出节点信息
{
printf("%d:%s-%s-%s-%s-%s\n", i++,
p->data.name, p->data.sex, p->data.work, p->data.tel,
p->data.email);
p = p->next;
}
printf("\n");
}
// main()函数
int main() {
ElemType elemType;
MessageCreat();
Print(head);
char name[100] = {0};
char name1[100] = {0};
char sex[100] = {0};
char work[100] = {0};
char tel[100] = {0};
char email[100] = {0};
printf("请按照姓名 性别 工作单位 电话 邮箱顺序依次输入相关信息,添加成员:\n");
scanf("%s %s %s %s %s", name, sex, work, tel, email);
if (strlen(name) >= 10 || strlen(sex) >= 10 || strlen(work) >= 15 || strlen(tel) >= 15 || strlen(email) >= 15) {
printf("输入信息有误,长度不合法。程序退出.\n");
return 0;
}
strcpy(elemType.name, name);
strcpy(elemType.sex, sex);
strcpy(elemType.work, work);
strcpy(elemType.tel, tel);
strcpy(elemType.email, email);
MessageAdd(head, &elemType);
Print(head);
printf("请输入要删除人的姓名:");
scanf("%s", name);
if (MessageDel(head, name)) {
printf("删除%s成功\n", name);
} else {
printf("删除%s失败\n", name);
};
Print(head);
printf("请输入要修改人的姓名:");
scanf("%s", name1);
if (strlen(name1) >= 10) {
printf("输入信息有误,姓名长度不合法。程序退出.\n");
return 0;
}
printf("请按照姓名 性别 工作单位 电话 邮箱顺序依次输入相关信息,修改信息:\n");
scanf("%s %s %s %s %s", name, sex, work, tel, email);
if (strlen(name) >= 10 || strlen(sex) >= 10 || strlen(work) >= 15 || strlen(tel) >= 15 || strlen(email) >= 15) {
printf("输入信息有误,长度不合法。程序退出.\n");
return 0;
}
strcpy(elemType.name, name);
strcpy(elemType.sex, sex);
strcpy(elemType.work, work);
strcpy(elemType.tel, tel);
strcpy(elemType.email, email);
if (MessageChange(head, name1, &elemType)) {
printf("修改%s信息成功\n", name1);
} else {
printf("修改%s信息失败\n", name1);
};
Print(head);
printf("请输入要查询人的姓名:");
scanf("%s", name);
if (strlen(name) >= 10) {
printf("输入信息有误,姓名长度不合法。程序退出.\n");
return 0;
}
if (MessageFind(head, name)) {
printf("查询%s成功\n", name);
} else {
printf("查询%s失败\n", name);
};
Print(head);
return 0;
} // main()函数结束