文章目录
- 通讯录 2.0
- 头文件
- 通讯录操作函数
- 通讯录主函数
通讯录 2.0
之前分享过使用顺序表思想实现通讯录,现在分享使用单链表实现的通讯录,我们只需要规定每个链表的元素是结构体类型,每个结构体内存放联系人信息即可。
**不断地练习才能熟练掌握!**代码逻辑很简单,实现时注意边界的处理即可。
头文件
//Contact.h#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define NAME_MAX 100
#define GENDER_MAX 4
#define TEL_MAX 11//用户数据
typedef struct PersonInfo
{char name[NAME_MAX];char gender[GENDER_MAX];size_t age;char tel[TEL_MAX];
}PeoInfo;typedef struct Contact
{PeoInfo data;struct Contact* next;
}contact;//初始化通讯录
void InitContact(contact** con);
//添加通讯录数据
void AddContact(contact** con);
//删除通讯录数据
void DelContact(contact** con);
//展示通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact** con);
//销毁通讯录数据
void DestroyContact(contact** con);
通讯录操作函数
通讯录
//Contact.c#include "Contact.h"void InitContact(contact** con)
{*con = NULL;
}void AddContact(contact** con)
{assert(con);PeoInfo new;printf("请输入新联系人的姓名:\n");scanf("%s", new.name);printf("请输入新联系人的年龄:\n");scanf("%zd", &new.age);printf("请输入新联系人的电话:\n");scanf("%s", new.tel);printf("请输入新联系人的性别:\n");scanf("%s", new.gender);contact* newnode = (contact*)malloc(sizeof(contact));if (NULL == newnode){perror("malloc");exit(-1);}newnode->data = new;newnode->next = NULL;if (*con == NULL){*con = newnode;return;}contact* cur = *con;while (cur->next){cur = cur->next;}cur->next = newnode;
}void DelContact(contact** con)
{//链表为空if (!(*con)){printf("通讯录为空!\n");return;}char newname[NAME_MAX] = { 0 };printf("请输入要删除的联系人的姓名:\n");scanf("%s", newname);//链表首结点元素匹配,避免后续prev为NULL时,对它解引用if (strcmp((*con)->data.name, newname) == 0){if ((*con)->next == NULL){free(*con);*con = NULL;}else{contact* tmp = (*con)->next;free(*con);*con = tmp;}printf("删除成功!\n");return;}contact* cur = (*con)->next;contact* prev = *con;while (cur){if (strcmp(newname, cur->data.name) == 0){prev->next = cur->next;free(cur);printf("删除成功!\n");return;}prev = cur;cur = cur->next;}printf("您要删除的联系人不存在!\n");
}void ShowContact(contact* con)
{if (!con){printf("通讯录为空!\n");}printf("----------------------------------------------------------------------------------\n");printf("%-11s %-11s %-11s %-11s\n", "姓名", "年龄", "电话", "性别");contact* cur = con;while (cur){printf("%-11s %-11zd %-11s %-11s\n", cur->data.name, cur->data.age, cur->data.tel, cur->data.gender);cur = cur->next;}printf("----------------------------------------------------------------------------------\n");
}void FindContact(contact* con)
{if (!con){printf("通讯录为空!\n");return;}printf("请输入您要查询的联系人的姓名:\n");char find[NAME_MAX] = { 0 };scanf("%s", find);contact* cur = con;while (cur){if (strcmp(find, cur->data.name) == 0){printf("查询结果如下:\n");printf("%-11s %-11zd %-11s %-11s\n", cur->data.name, cur->data.age, cur->data.tel, cur->data.gender);return;}cur = cur->next;}printf("您要查询的联系人不存在!\n");
}void ModifyContact(contact** con)
{if (!(*con)){printf("通讯录为空!\n");return;}printf("请输入您要修改的联系人的姓名:\n");char obj[NAME_MAX] = { 0 };scanf("%s", obj);//char newname[NAME_MAX] = { 0 };//int newage = 0;//char newtel[TEL_MAX] = { 0 };//char newgender[GENDER_MAX] = { 0 };contact* cur = *con;while (cur){if (strcmp(obj, cur->data.name) == 0){printf("请输入修改后的姓名:\n");scanf("%s", cur->data.name);printf("请输入修改后的年龄:\n");scanf("%zd", &(cur->data.age));printf("请输入修改后的电话:\n");scanf("%s", cur->data.tel);printf("请输入修改后的性别:\n");scanf("%s", cur->data.gender);printf("修改成功!\n");return;}cur = cur->next;}printf("您要修改的联系人不存在!\n");
}void DestroyContact(contact** con)
{contact* cur = *con;while (cur){contact* tail = cur->next;free(cur);cur = tail;}*con = NULL;
}
通讯录主函数
包括菜单、读取数据、保存数据的函数实现。
//test.c#include "Contact.h"
//菜单
void menu()
{printf("******************通讯录*******************\n");printf("*******1.添加联系人 2.删除联系人*******\n");printf("*******3.修改联系人 4.查询联系人*******\n");printf("*******5.展示通讯录 0.退出通讯录*******\n");printf("*******************************************\n");
}//载入数据函数
void LoadContact(contact** con)
{FILE* pf = fopen("Contact.txt", "rb");if (NULL == pf){perror("fopen");exit(-1);}PeoInfo buff;while (fread(&buff, sizeof(PeoInfo), 1, pf)){contact* newnode = (contact*)malloc(sizeof(contact));if (NULL == newnode){perror("malloc");exit(-1);}newnode->next = NULL;newnode->data = buff;if (*con == NULL){*con = newnode;continue;}contact* cur = *con;while (cur->next){cur = cur->next;}cur->next = newnode;}printf("历史数据载入成功!\n");
}//保存数据函数
void SaveContact(contact* con)
{FILE* pf = fopen("Contact.txt", "wb");if (NULL == pf){perror("fopen");exit(-1);}contact* cur = con;while (cur){PeoInfo wr = cur->data;fwrite(&wr, sizeof(PeoInfo), 1, pf);cur = cur->next;}printf("数据保存成功!\n");
}//主函数
int main()
{contact* con;InitContact(&con);LoadContact(&con);int input = 0;do{menu();printf("请输入你想执行的操作:\n");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:ModifyContact(&con);break;case 4:FindContact(con);break;case 5:ShowContact(con);break;case 0:printf("退出通讯录\n");break;default:printf("输入非法,请重新输入!\n");break;}} while (input);SaveContact(con);DestroyContact(&con);return 0;
}
执行程序的效果: