动态版通讯录
动态版通讯录与静态版通讯录最大的不同就在于结构体的定义,多了一个容量的变量。而且添加联系人的时候要判断容量是否足够,所以我们可以封装一个函数来判断容量是否足够,不够的话进行扩容
而且涉及到了动态内存,那我们就要封装一个函数进行内存的释放
test.c
#define _CRT_SECURE_NO_WARNINGS #include "contact.h" /* * 添加联系人信息 删除指定联系人信息 查找指定联系人信息 修改指定联系人信息 显示所有联系人信息 清空所有联系人 以名字排序所有联系人 */ enum option { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, CLEAR, SORTNAME }; void menu() { printf("*******************************************\n"); printf("****** 1.add 2.del ******\n"); printf("****** 3.search 4.modify****\n"); printf("****** 5.show 6.clear ****\n"); printf("****** 7.sortName 0.exit *****\n"); printf("*******************************************\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 CLEAR: ClearContact(&con); break; case SORTNAME: SortContact(&con); break; case EXIT: DestroyContact(&con); printf("退出通讯录\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }
contact.h
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <assert.h> #include <stdlib.h> #define DEFAULT_SZ 3 #define INC_SZ 2 #define MAX 1000 #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 AddContact(Contact* pc); //打印 void ShowContact(const Contact* pc); //删除 void DelContact(Contact* pc); //查找 void SearchContact(Contact* pc); //修改 void ModifyContact(Contact* pc); //清空 void ClearContact(Contact* pc); //排序 void SortContact(Contact* pc); //销毁 void DestroyContact(Contact* pc);
contact.c
#define _CRT_SECURE_NO_WARNINGS #include "contact.h" int InitContact(Contact* pc) { assert(pc); pc->count = 0; pc->data = (PeoInfo*)calloc(3,sizeof(PeoInfo)); if (pc->data == NULL) { printf("InitContact:%s\n", strerror(errno)); return 1; } pc->capacity = DEFAULT_SZ; return 0; } void CheckCapacity(Contact* pc) { if (pc->count == pc->capacity) { PeoInfo* ptr = 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 AddContact(Contact* pc) { assert(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) { assert(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%-3d\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[]) { assert(pc); int i = 0; for (i = 0; i < pc->count; i++) { if (0 == strcmp(pc->data[i].name, name)) { return i; } } return -1; } void DelContact(Contact* pc) { char name[MAX_NAME] = { 0 }; assert(pc); int i = 0; if (pc->count == 0) { printf("通讯录为空,没有信息可以删除\n"); return; } printf("请输入要删除人的名字:>"); scanf("%s", name); //查找 int pos = FindByName(pc, name); if (pos == -1) { printf("要删除的人不存在\n"); return; } //删除 for (i = pos; i < pc->count - 1; i++) { pc->data[i] = pc->data[i + 1]; } pc->count--; printf("删除成功\n"); } void SearchContact(Contact* pc) { char name[MAX_NAME] = { 0 }; assert(pc); printf("请输入要查找人的名字:>"); scanf("%s", name); int pos = FindByName(pc, name); if (pos == -1) { printf("要查找的人不存在\n"); return; } else { printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-20s\t%-3d\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) { char name[MAX_NAME] = { 0 }; assert(pc); printf("请输入要修改人的名字:>"); scanf("%s", name); int pos = FindByName(pc, name); if (pos == -1) { printf("要修改的人不存在\n"); return; } else { printf("请输入名字:"); scanf("%s", pc->data[pos].name); printf("请输入年龄:"); scanf("%d", &pc->data[pos].age); printf("请输入性别:"); scanf("%s", pc->data[pos].sex); printf("请输入电话:"); scanf("%s", pc->data[pos].tele); printf("请输入地址:"); scanf("%s", pc->data[pos].addr); printf("修改成功\n"); } } void ClearContact(Contact* pc) { assert(pc); pc->count = 0; memset(pc->data, 0, sizeof(pc->data)); printf("清空成功!\n"); } int cmp_by_name(const void* e1, const void* e2) { return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name); } void SortContact(Contact* pc) { assert(pc); for (int i = 0; i < pc->count - 1; i++) { qsort(pc->data, pc->count, sizeof(pc->data[0]), cmp_by_name); } printf("排序成功!\n"); } void DestroyContact(Contact* pc) { assert(pc); free(pc->data); pc->data = NULL; }