通讯录链表管理(C语言实现)

**问题描述:**

用双链表做数据结构,编写一个通讯录管理系统。本系统应具有信息的增删改查等功能。

**基本要求及提示:**

(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()函数结束

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的用链表实现通讯录管理系统的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义通讯录结构体 typedef struct contact { char name[20]; char phone[20]; struct contact *next; } Contact; // 声明函数 void add_contact(Contact **head); void delete_contact(Contact **head); void search_contact(Contact *head); void display_contacts(Contact *head); void save_contacts(Contact *head); int main() { Contact *head = NULL; // 初始化头指针为空 int choice; while (1) { printf("\n1. 添加联系人\n"); printf("2. 删除联系人\n"); printf("3. 查找联系人\n"); printf("4. 显示所有联系人\n"); printf("5. 保存联系人到文件\n"); printf("0. 退出\n"); printf("请输入选项:"); scanf("%d", &choice); switch (choice) { case 1: add_contact(&head); break; case 2: delete_contact(&head); break; case 3: search_contact(head); break; case 4: display_contacts(head); break; case 5: save_contacts(head); break; case 0: exit(0); default: printf("无效选项,请重新输入!\n"); } } return 0; } // 添加联系人 void add_contact(Contact **head) { Contact *new_contact = (Contact *) malloc(sizeof(Contact)); printf("请输入姓名:"); scanf("%s", new_contact->name); printf("请输入电话号码:"); scanf("%s", new_contact->phone); new_contact->next = *head; *head = new_contact; printf("联系人添加成功!\n"); } // 删除联系人 void delete_contact(Contact **head) { char name[20]; printf("请输入要删除的联系人姓名:"); scanf("%s", name); Contact *prev = NULL; Contact *current = *head; while (current != NULL && strcmp(current->name, name) != 0) { prev = current; current = current->next; } if (current == NULL) { printf("未找到联系人!\n"); return; } if (prev == NULL) { *head = current->next; } else { prev->next = current->next; } free(current); printf("联系人删除成功!\n"); } // 查找联系人 void search_contact(Contact *head) { char name[20]; printf("请输入要查找的联系人姓名:"); scanf("%s", name); Contact *current = head; while (current != NULL) { if (strcmp(current->name, name) == 0) { printf("姓名:%s,电话:%s\n", current->name, current->phone); return; } current = current->next; } printf("未找到联系人!\n"); } // 显示所有联系人 void display_contacts(Contact *head) { if (head == NULL) { printf("通讯录为空!\n"); return; } Contact *current = head; while (current != NULL) { printf("姓名:%s,电话:%s\n", current->name, current->phone); current = current->next; } } // 保存联系人到文件 void save_contacts(Contact *head) { if (head == NULL) { printf("通讯录为空!\n"); return; } FILE *fp = fopen("contacts.txt", "w"); if (fp == NULL) { printf("保存失败!\n"); return; } Contact *current = head; while (current != NULL) { fprintf(fp, "%s,%s\n", current->name, current->phone); current = current->next; } fclose(fp); printf("保存成功!\n"); } ``` 这个示例代码实现了添加、删除、查找、显示、保存联系人的功能,其中通讯录使用链表来存储,每个节点包括姓名、电话和下一个节点的指针。在添加联系人时,新的节点会插入到链表的头部;在删除联系人时,需要遍历链表找到要删除的节点并将其从链表中删除;在查找联系人时,也需要遍历链表并按姓名进行比较;在显示所有联系人时,只需要遍历链表并输出每个节点的信息;在保存联系人到文件时,可以使用文件 I/O 将每个节点的信息入到一个文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值