C语言通讯录管理系统
今天也要写bug、 人气:0要实现一个通讯录管理系统,需要用到结构体、指针、文件操作、动态管理等内容。
效果展示:
实现思路
通讯录中的联系人包括姓名、年龄、性别、电话、住址,因此可以定义一个结构体PeoInfo来存储这些信息。
同时,由于通讯录需要记录当前的大小,以此来方便我们对通讯录realloc进行扩容,所以需要定义通讯录结构体Contact来保存这些信息,其中该结构体中可以嵌套一个PeoInfo类型的指针。
当定义完结构体以后,就可以对定义的结构体进行增删查改,其中可以先使用malloc对通讯录结构体进行初始化,然后再完成添加、删除、查找、修改、保存、排序、清空等一系列函数。
在保存时,需要用到文件指针将数据保存到文件中,因此在一开始当前目录下需要一个相应的文件。
同时在初始化时,也要将文件中的数据读取到我们的结构体指针指向的内容中。
在这里使用contact.txt文件来保存信息:
为了方便,我们将函数声明,函数实现,以及游戏的实现放到三个不同文件里:
contact.h内容
#pragma once #include<stdio.h> #include<string.h> #include<stdlib.h> #include<errno.h> #define MAX_NAME 10//名字的大小 #define MAX_SEX 5//性别大小 #define MAX_TELE 15//电话大小 #define MAX_ADDR 30//地址大小 #define DEFAULT_SZ 3 //通讯录默认的大小 enum Option { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT, SAVE, CLEAR }; struct PeoInfo { char name[MAX_NAME]; int age; char sex[MAX_SEX]; char tele[MAX_TELE]; char addr[MAX_ADDR]; }; //通讯录类型 struct Contact { struct PeoInfo* data;//存放信息 int size;//记录当前已经有的元素个数 int capacity;//当前通讯录的最大容量 }; //初始化通讯录 void InitContact(struct Contact* ps); //增加通讯录内容 void AddContact(struct Contact* ps); //打印通讯录信息 void ShowContact(const struct Contact* ps); //删除通讯录信息 void DelContact(struct Contact* ps); //查找通讯录信息 void SearchContact(const struct Contact* ps); //修改指定联系人 void ModifyContact(struct Contact* ps); //按姓名排序 void SortContact(struct Contact* ps); //释放动态开辟的内存 void DestroyContact(struct Contact* ps); //保存通讯录 void SaveContact(struct Contact* ps); //加载文件中的信息到通讯录 void LoadContact(struct Contact* ps); //清空通讯录 void ClearContact(struct Contact* ps);
这个文件中主要包括结构体的创建,以及各种函数的声明。
contact.c内容
#include"contact.h" void InitContact(struct Contact* ps) { ps ->data =(struct PeoInfo*) malloc(DEFAULT_SZ * sizeof(struct PeoInfo)); if (ps->data == NULL) { printf("空间开辟失败"); return; } ps->size = 0; ps->capacity = DEFAULT_SZ; //把文件中存放的信息加载到通讯录中 LoadContact(ps); } void CheckCapacity(struct Contact* ps) { if (ps->size == ps->capacity) { struct PeoInfo* ptr = (struct PeoInfo*)realloc(ps->data, (ps->capacity + 5) * sizeof(struct PeoInfo)); if (ptr != NULL) { ps->data = ptr; ps->capacity += 5; } } } void LoadContact(struct Contact* ps) { struct PeoInfo tmp = { 0 }; FILE* pfRead = fopen("contact.txt", "rb"); if (pfRead == NULL) { printf("文件不存在:%s\n", strerror(errno)); return; } //读取文件 while (fread(&tmp, sizeof(struct PeoInfo), 1, pfRead)) { CheckCapacity(ps); ps->data[ps->size] = tmp; ps->size++; } fclose(pfRead); pfRead = NULL; } void AddContact(struct Contact* ps) { //检测当前通讯录的容量,如果满了则增容 CheckCapacity(ps); printf("请输入名字->"); scanf("%s", ps->data[ps->size].name); printf("请输入年龄->"); scanf("%d", &(ps->data[ps->size].age)); printf("请输入性别->"); scanf("%s", ps->data[ps->size].sex); printf("请输入电话->"); scanf("%s", ps->data[ps->size].tele); printf("请输入地址->"); scanf("%s", ps->data[ps->size].addr); ps->size++; printf("添加成功\n"); } void ShowContact(const struct Contact* ps) { if (ps->size == 0) { printf("通讯录为空\n"); } else { int i = 0; printf("%-10s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址"); { for (i = 0; i < ps->size; i++)//打印每个通讯录元素 { printf("%-10s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr); } } } } //查找联系人位置 int FindByName(const struct Contact* ps, char name[MAX_NAME]) { //查找要删除人的位置 int i = 0; for (i = 0; i < ps->size; i++) { if (0 == strcmp(ps->data[i].name, name)) { return i;//找到返回下标 } } return -1;//找不到返回-1 } void DelContact(struct Contact* ps) { char name[MAX_NAME]; printf("请输入要删除人的名字:->"); scanf("%s", name); //查找要删除人的位置 int pos=FindByName(ps, name);//找到返回名字所在的下标,找不到返回-1 if (pos==-1) { printf("联系人不存在\n"); } else { //删除 int j = 0; for (j = pos; j < ps->size-1; j++) { ps->data[j] = ps->data[j + 1]; } ps->size--; printf("删除成功\n"); } } void SearchContact(const struct Contact* ps) { char name[MAX_NAME]; printf("请输入要查找人的名字:->"); scanf("%s", name); int pos = FindByName(ps, name);//找到返回名字所在的下标,找不到返回-1 if (pos == -1) { printf("联系人不存在\n"); } else { printf("%-10s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-10s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[pos].name, ps->data[pos].age, ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].addr); } } void ModifyContact(struct Contact* ps) { char name[MAX_NAME]; printf("请输入要修改人的名字:->"); scanf("%s", name); int pos = FindByName(ps, name);//找到返回名字所在的下标,找不到返回-1 if (pos == -1) { printf("联系人不存在\n"); } else { printf("请输入名字->"); scanf("%s", ps->data[pos].name); printf("请输入年龄->"); scanf("%d", &(ps->data[pos].age)); printf("请输入性别->"); scanf("%s", ps->data[pos].sex); printf("请输入电话->"); scanf("%s", ps->data[pos].tele); printf("请输入地址->"); scanf("%s", ps->data[pos].addr); printf("修改完成\n"); } } void SortContact(struct Contact* ps) { for (int i = 0; i < ps->size - 1; ++i) { for (int j = 0; j < ps->size - i - 1; ++j) { if (strcmp(ps->data[j].name, ps->data[j + 1].name) > 0) { struct PeoInfo tmp = ps->data[j]; ps->data[j] = ps->data[j + 1]; ps->data[j + 1] = tmp; } } } printf("按姓名排序成功\n"); } //释放动态开辟的空间 void DestroyContact(struct Contact* ps) { free(ps->data); ps->data=NULL; } void SaveContact(struct Contact* ps) { FILE* pfWrite = fopen("contact.txt", "wb"); if (pfWrite == NULL) { printf("%s\n", strerror(errno)); return; } //将通讯录的信息写入文件 int i = 0; for (i = 0; i < ps->size; i++) { fwrite(&(ps->data[i]), sizeof(struct PeoInfo), 1, pfWrite); } printf("保存成功\n"); fclose(pfWrite); pfWrite = NULL; } void ClearContact(struct Contact* ps) { printf("确定要清空通讯录吗?<Y/N> :>"); char ch; getchar();//清空缓存区里面的\n scanf("%c", &ch); if (ch == 'Y' || ch == 'y') { ps->size = 0; memset(ps->data, 0, sizeof(ps->data)); printf("清空成功\n"); } else { printf("取消清空\n"); } }
在这个文件中我们将声明的函数进行了定义,用到的方法都比较简单。
test.c内容
#include"contact.h" void menu() { printf("**************************************************\n"); printf("****1.添加联系人 2.删除联系人**************\n"); printf("****3.查找联系人 4.修改联系人*************\n"); printf("****5.展示所有联系人 6.按姓名排序联系人********\n"); printf("****7.保存通讯录 8.清空通讯录*************\n"); printf("**************0.退出通讯录************************\n"); printf("**************************************************\n"); } int main() { int input = 0; //创建通讯录 int size = 0; struct Contact con;//con是通讯录 //初始化通讯录 InitContact(&con); do { menu(); printf("请选择->"); scanf("%d", &input); switch (input) { case ADD: AddContact(&con); system("pause"); system("cls"); break; case DEL: DelContact(&con); system("pause"); system("cls"); break; case SEARCH: SearchContact(&con); system("pause"); system("cls"); break; case MODIFY: ModifyContact(&con); system("pause"); system("cls"); break; case SHOW: ShowContact(&con); system("pause"); system("cls"); break; case SORT: SortContact(&con); system("pause"); system("cls"); break; case SAVE: SaveContact(&con); system("pause"); system("cls"); break; case CLEAR: ClearContact(&con); system("pause"); system("cls"); break; case EXIT: SaveContact(&con); //释放动态开辟的内存 DestroyContact(&con); break; default: printf("选择错误\n"); break; } } while (input); }
在这个文件中将对菜单进行打印,同时进行函数的调用。
加载全部内容