test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"void menu(){printf("=====================================\n");printf("============1.增加联系人=============\n");printf("============2.删除联系人=============\n");printf("============3.查找联系人=============\n");printf("============4.修改联系人=============\n");printf("============5.打印通讯录=============\n");printf("============6.排序通讯录=============\n");printf("============0.退出通讯录=============\n");printf("=====================================\n");
}
int main()
{contact con;//struct contact con;//新建一个通讯录包括个人信息结构体数组,内存Initcontact(&con);loadcontact(&con);int op = -1;do {menu();printf("请输入选择\n");scanf("%d", &op);switch (op){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:FindContact(&con);break;case 4:ModifyContact(&con);break;case 5:ShowContact(&con);break;case 6:Qsortcontact(&con);break;case 0:printf("正在退出程序\n");break;default:printf("重新输入\n");break;}} while (op);save_contact(&con);//DestroyContact(&con);return 0;
}
contact.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#define NAME_MAX 100
#define GENDER_MAX 10
#define TEL_MAX 11
#define ADD_MAX 100typedef struct PersonInfo//个人信息
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char add[ADD_MAX];
}PeoInfo;typedef struct contact
{PeoInfo* arr;//结构体数组,数组的每个元素都是结构体,每个结构体都表示一个人的个人信息int capacity;//容量int size;
}contact;void Initcontact(contact* ps);
void capacitycontact(contact* ps);
void AddContact(contact*ps);
void ShowContact(contact*ps);void DelContact(contact*ps);
void FindContact(contact*ps);
void ModifyContact(contact* ps);void DestroyContact(contact*ps);
void Qsortcontact(contact* ps);
void save_contact(contact* ps);
void loadcontact(contact* ps);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"void Initcontact(contact* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->size=0;
}void capacitycontact(contact* ps)
{assert(ps);if (ps->capacity == ps->size){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;PeoInfo* tmp = (PeoInfo*)realloc(ps->arr, newcapacity * sizeof(PeoInfo));//这里增加内存每次需要增加最少一个个人信息结构体的大小,就是struct personinfo大小if (tmp == NULL){perror("realloc fail");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}
}void AddContact(contact* ps)
{assert(ps);capacitycontact(ps);PeoInfo con1;//新建一个结构体变量先保存下来数据,在最后选择插入地址printf("开始录入信息\n");printf("请输入姓名\n");scanf("%s", con1.name);printf("请输入性别\n");scanf("%s", con1.gender);printf("请输入年龄\n");scanf("%d", &con1.age);printf("请输入电话\n");scanf("%s", con1.tel);printf("请输入地址\n");scanf("%s", con1.add);printf("录入信息成功\n");ps->arr[ps->size++] = con1;
}void ShowContact(contact* ps) {assert(ps);printf("%-15s %-5s %-5s %-12s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < ps->size; i++){printf("%-15s %-5s %-5d %-12s %-30s\n", ps->arr[i].name, ps->arr[i].gender, ps->arr[i].age, ps->arr[i].tel, ps->arr[i].add);//printf("%s %s %d %s %s\n", ps->arr[i].name, ps->arr[i].gender, ps->arr[i].age, ps->arr[i].tel, ps->arr[i].add);}}int findbyname(contact* ps, char*name) {for (int i = 0; i < ps->size; i++){if (strcmp(ps->arr[i].name, name) == 0) {//strcmp,前后相等返回0,前大于后返回大于1的数,前小于后返回小于1的数return i;//进来就是大于0找到了,返回当前size坐标}}return -1;
}
void FindContact(contact* ps)
{char name[NAME_MAX];printf("请输入要查找到的用户名\n");scanf("%s", name);int findindex = findbyname(ps, name);if (findindex == -1) {printf("没找到\n");return;}else {printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");printf("%s %s %d %s %s\n", ps->arr[findindex].name, ps->arr[findindex].gender, ps->arr[findindex].age, ps->arr[findindex].tel, ps->arr[findindex].add);}}
void DelContact(contact* ps)
{assert(ps);char name[NAME_MAX];printf("输入要删除的姓名");scanf("%s", name);int findindex = findbyname(ps, name);if (findindex == -1) {printf("没找到\n");return;}else {for (int i = findindex; i < ps->size-1; i++) {ps->arr[i] = ps->arr[i+1];}printf("删除联系人成功\n");ps->size--;}}void ModifyContact(contact* ps) {assert(ps);char name[NAME_MAX];printf("输入要修改的姓名");scanf("%s", name);int findindex = findbyname(ps, name);if (findindex == -1) {printf("没找到\n");return;}else {printf("开始修改信息\n");printf("请输入姓名\n");scanf("%s", ps->arr[findindex].name);printf("请输入性别\n");scanf("%s", ps->arr[findindex].gender);printf("请输入年龄\n");scanf("%d", &ps->arr[findindex].age);printf("请输入电话\n");scanf("%s", ps->arr[findindex].tel);printf("请输入地址\n");scanf("%s", ps->arr[findindex].add);printf("修改信息成功\n");}}void DestroyContact(contact* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->capacity = ps->size = 0;}int cmp(const PeoInfo* a, const PeoInfo* b)//比较年纪
{return a->age - b->age;
}int cmp2(const PeoInfo* a, const PeoInfo* b)//比较名字
{return strcmp((char*)a->name , (char*)b->name);
}void Qsortcontact(contact* ps)
{assert(ps);int tmp = 0;printf("1.年纪排序 2.姓名排序\n");scanf("%d", &tmp);if (tmp == 1) {qsort(ps->arr, ps->size, sizeof(PeoInfo), cmp);printf("排序成功\n");}else {qsort(ps->arr, ps->size, sizeof(PeoInfo), cmp2);printf("排序成功\n");}}void save_contact(contact* ps)
{//在每次退出程序,需要保存输入的数据,这个功能封装在save_contact函数中//注意每次对文件操作都要检查剩余容量FILE* pf = fopen("contact111.txt", "wb");if (pf == NULL){perror("open file");return;}//capacitycontact(ps);for (int i = 0; i < ps->size; i++){fwrite(ps->arr + i, sizeof(PeoInfo), 1, pf);//size_t fwrite(const void* ptr, size_t size, size_t count, FILE * stream);//ptr:一个指向要写入数据的内存块的指针。//size:要写入的数据块中每个数据项的大小(以字节为单位)。//count:要写入的数据项的数量。//stream:一个指向 FILE 对象的指针,该对象指定了一个输出流。}fclose(pf);
}void loadcontact(contact* ps)
{FILE* pf = fopen("contact111.txt", "rb");if (pf == NULL){perror("open file");return;}PeoInfo info;while (fread(&info, sizeof(PeoInfo), 1, pf)){capacitycontact(ps);ps->arr[ps->size++] = info;}printf("通讯录载入成功\n");fclose(pf);
}