C语言通讯录
whispar 人气:0一、代码展示
test.c
✅使用枚举类型,使得菜单部分的代码可读性更强,便于理解
#define _CRT_SECURE_NO_WARNINGS #include"contact.h" enum Option { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT }; void menu() { printf("*******\ 1.add 2.del /*******\n"); printf("*******\ 3.search 4.modify /*******\n"); printf("*******\ 5.show 6.sort /*******\n"); } int main(){ int input = 0; Contact con; //通讯录 //结构体传参 InitContact(&con); //结构体传参 do { menu(); printf("请选择:> "); scanf("%d", &input); switch (input) { case ADD: AddContact(&con); break; case DEL: DelContact(&con); break; case SEARCH: SearchContact(&con); break; case MODIFY: ModifyContact(&con); break; case SHOW: ShowContact(&con); break; case SORT: SortContact(&con); break; case EXIT: SaveContact(&con); DestroyContact(&con); printf("退出通讯录\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }
contact.c
✅在contact.c中静态的版本无法满足我们的需求,因此我们在动态的版本当中使用realloc函数就可以做到对动态开辟内存大小,我们可以封装一个函数来判断容量是否足够,不够的话进行扩容。
✅在contact.c中文件的版本可以将创建的数据存储在本地,当程序退出时,数据依然存在,使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。
#define _CRT_SECURE_NO_WARNINGS 1 #include "contact.h" //静态的版本 //void InitContact(Contact* pc) //{ // assert(pc); // pc->count = 0; // memset(pc->data, 0, sizeof(pc->data)); //} void CheckCapacity(Contact* pc) { if (pc->count == pc->capacity) { PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo)); if (ptr == NULL) { printf("AddContact::%s\n", strerror(errno)); return; } else pc->data = ptr; pc->capacity += INC_SZ; printf("增容成功\n"); } } void LoadContact(Contact* pc) FILE* pfRead = fopen("contact.txt", "rb"); if (pfRead == NULL) perror("LoadContact"); return; PeoInfo tmp = { 0 }; while (fread(&tmp, sizeof(PeoInfo), 1, pfRead) == 1) CheckCapacity(pc); pc->data[pc->count] = tmp; pc->count++; fclose(pfRead); pfRead = NULL; //动态的版本 int InitContact(Contact* pc) assert(pc); pc->count = 0; pc->data = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo)); if (pc->data == NULL) printf("InitContact::%s\n", strerror(errno)); return 1; pc->capacity = DEFAULT_SZ; //加载文件的信息到通讯录中 LoadContact(pc); return 0; void DestroyContact(Contact* pc) free(pc->data); pc->data = NULL; //void AddContact(Contact* pc) // if (pc->count == MAX) // { // printf("通讯录已满,无法添加\n"); // return; // } // // // printf("请输入名字:>"); // scanf("%s", pc->data[pc->count].name); // printf("请输入年龄:>"); // scanf("%d", &(pc->data[pc->count].age)); // printf("请输入性别:>"); // scanf("%s", pc->data[pc->count].sex); // printf("请输入电话:>"); // scanf("%s", pc->data[pc->count].tele); // printf("请输入地址:>"); // scanf("%s", pc->data[pc->count].addr); // // pc->count++; // printf("增加成功\n"); void AddContact(Contact* pc) //增容 CheckCapacity(pc); // printf("请输入名字:>"); scanf("%s", pc->data[pc->count].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pc->count].age)); printf("请输入性别:>"); scanf("%s", pc->data[pc->count].sex); printf("请输入电话:>"); scanf("%s", pc->data[pc->count].tele); printf("请输入地址:>"); scanf("%s", pc->data[pc->count].addr); pc->count++; printf("增加成功\n"); void ShowContact(const Contact* pc) int i = 0; printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址"); for (i = 0; i < pc->count; i++) printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr); static int FindByName(Contact* pc, char name[]) if (0 == strcmp(pc->data[i].name, name)) return i; return -1; void DelContact(Contact* pc) char name[MAX_NAME] = { 0 }; if (pc->count == 0) printf("通讯录为空,没有信息可以删除\n"); printf("请输入要删除人的名字:>"); scanf("%s", name); //删除 //1. 查找 int pos = FindByName(pc, name); if (pos == -1) printf("要删除的人不存在\n"); //2. 删除 for (i = pos; i < pc->count - 1; i++) pc->data[i] = pc->data[i + 1]; pc->count--; printf("删除成功\n"); void SearchContact(Contact* pc) printf("请输入要查找人的名字:>"); printf("要查找的人不存在\n"); //2. 打印 printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr); void ModifyContact(Contact* pc) printf("请输入要修改人的名字:>"); printf("要修改的人不存在\n"); printf("要修改的人的信息已经查找到,接下来开始修改\n"); //2. 修改 scanf("%s", pc->data[pos].name); scanf("%d", &(pc->data[pos].age)); scanf("%s", pc->data[pos].sex); scanf("%s", pc->data[pos].tele); scanf("%s", pc->data[pos].addr); printf("修改成功\n"); int cmp_peo_by_name(const void* e1, const void* e2) return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name); //按照名字来排序 void SortContact(Contact* pc) qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_peo_by_name); printf("排序成功\n"); void SaveContact(const Contact* pc) FILE* pfWrite = fopen("contact.txt", "wb"); if (pfWrite == NULL) perror("SaveContact"); //写文件-二进制的形式 fwrite(pc->data + i, sizeof(PeoInfo), 1, pfWrite); fclose(pfWrite); pfWrite = NULL;
contact.h
#pragma once #include <string.h> #include <stdio.h> #include <assert.h> #include <stdlib.h> #define DEFAULT_SZ 3 #define INC_SZ 2 #define MAX 100 #define MAX_NAME 20 #define MAX_SEX 10 #define MAX_TELE 12 #define MAX_ADDR 30 //类型的声明 // //人的信息 typedef struct PeoInfo { char name[MAX_NAME]; int age; char sex[MAX_SEX]; char tele[MAX_TELE]; char addr[MAX_ADDR]; } PeoInfo; //通讯录 //静态版本 //typedef struct Contact //{ // PeoInfo data[MAX];//存放人的信息 // int count;//记录当前通讯录中实际人的个数 //}Contact; //动态的版本 typedef struct Contact { PeoInfo* data;//存放人的信息 int count;//记录当前通讯录中实际人的个数 int capacity;//当前通讯录的容量 }Contact; //初始化通讯录 int InitContact(Contact* pc); //销毁通讯录 void DestroyContact(Contact* pc); //增加联系人都通讯录 void AddContact(Contact* pc); //打印通讯中的信息 void ShowContact(const Contact* pc); //删除指定联系人 void DelContact(Contact* pc); //查找指定联系人 void SearchContact(Contact* pc); //修改指定联系人 void ModifyContact(Contact* pc); //排序通讯录中内容 //按照名字来排序 //按照年龄来排序 //... void SortContact(Contact* pc); //保存通讯录的信息到文件 void SaveContact(const Contact* pc); //加载文件的信息到通讯录 void LoadContact(Contact* pc);
二、效果展示
静态版本基本功能的实现
动态版本扩容功能的实现
文件版本保存本地功能实现
加载全部内容