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 100
typedef 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);
}