目录
一、头文件部分
二、测试部分
三、通讯录实现的功能模块介绍
1.初始化通讯录
静态版本
动态版本
将通讯录信息保存到文件
加载文件信息到通讯录
2.添加联系人
静态版本
动态版本
核查通讯录容量
3.销毁通讯录
4.显示所有的联系人
5.显示单个联系人
6.删除指定的联系人
7.查找指定的联系人
8.修改指定的联系人
9.排序所有联系人
10.将通讯录信息保存到文件中
一、头文件声明
#pragma once
struct people_info//联系人结构体
{
int age;//考虑到结构体内存对齐问题
char name[32];
char sex[8];
char phone[16];
char address[32];
};
#define CAPACITY_cur_size 3
#define MAX_PEOPLE 1000
struct address_book//通讯录结构体
{
struct people_info *p;
int capacity;//最大容量,默认就是MAX_PEOPLE
int cur_size;//当前联系人数量
};
extern void book_init(struct address_book *book);//初始化通讯录
extern int book_add(struct address_book *book);//增加联系人
extern void book_print(struct address_book *book);//打印通讯录
extern int find(struct address_book *book);//查找指定联系人
extern int book_del(struct address_book *book);//删除指定联系人
extern int book_mod(struct address_book *book);//修改指定联系人
extern int book_clear(struct address_book *book);//清空通讯录
extern int book_sort(struct address_book *book);//联系人排序
extern void book_destory(struct address_book *book);//销毁通讯录
extern void book_saveaddress(struct address_book *book);//保存信息到通讯录
extern void book_Loadaddress(struct address_book *book);//加载文件中的信息到通讯录中
二、
这部分主要完成通讯录各个功能的入口,及一个菜单显示页面。具体实现程序如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include"child.h"
int main()
{
struct address_book book;
book_init(&book);//初始化只需要一次,所以不需放在while循环中
while (1)
{
printf("**************通讯录**************\n");
printf("*****1.添加联系人 2.查找联系人*****\n");
printf("*****3.修改联系人 4.删除联系人*****\n");
printf("*****5.排序联系人 6.打印通讯录*****\n");
printf("*********** 0.退出通讯录**********\n");
int choice = -1;
printf("请输入操作:");
scanf("%d", &choice);
switch (choice)
{
case 1:
book_add(&book);
break;
case 2:
find(&book);
break;
case 3:
book_mod(&book);
break;
case 4:
book_del(&book);
break;
case 5:
book_sort(&book);
break;
case 6:
book_print(&book);
break;
case 0:
//book_saveaddress(&book);
book_destory(&book);
break;
default:
printf("选项错误,请重新输入!");
break;
}
}
system("pause");
return 0;
}
三、通讯录实现的功能模块介绍
1.初始化通讯录
静态版本:
void book_init(struct address_book *book)
{
book->cur_size = 0;//默认没有信息
//memset(book->p, 0, MAX*sizeof(struct people_info));
//memset()函数原型是extern void *memset(void *buffer, int c, int count)
//buffer:为指针或是数组,c:是赋给buffer的值,count:是buffer的长度.
memset(book->p, 0, sizeof(book->p));
}
动态版本:
void book_init(struct address_book *book)
{
book->capacity = CAPACITY_cur_size;
book->cur_size = 0;
book->p= (struct people_info*)malloc(book->capacity * sizeof(struct people_info));
if (book->p == NULL)
{
printf("初始化失败\n");
exit(1);//exit(1)表示异常退出
}
//加载文件信息到通讯录
book_Loadaddress(book);
return;
}
将通讯录信息保存到文件中
void book_saveaddress(struct address_book *book)
{
FILE* pout = fopen("address_book.dat", "wb");//打开文件,二进制写
if (pout == NULL)
{
printf("打开失败\n");
return;
}
for (int i = 0; i < book->cur_size; i++)
{
fwrite(book->p + i, sizeof(struct people_info), 1, pout);
}
printf("保存成功\n");
fclose(pout);
pout = 0;
}
加载文件信息到通讯录
void book_Loadaddress(struct address_book *book)
{
FILE* puin = fopen("address_book.dat", "rb");
if (puin == NULL)
{
printf("打开失败\n");
return;
}
struct people_info tmp = { 0 };//相当于中间变量
while (fread(&tmp, sizeof(struct people_info), 1, puin))//取出一个单位的内容到tmp的地址中
{
if (expansion(book) == 0)//相当于增加,所以要判断容量
{
printf("容量不足且扩容失败\n");
return;
}
book->p[book->cur_size] = tmp;//当前位置的值
book->cur_size++;
}
fclose(puin);//读完关闭文件,并将指针滞空
puin = NULL;
}
2.添加联系人
静态版本:
int book_add(struct address_book *book)
{
if (book->cur_size == MAX_PEOPLE)
{
printf("通讯录已满,无法增加新的联系人\n");
return;
}
printf("请输入联系人姓名:");
scanf("%s", book->p[book->cur_size].name);
printf("请输入联系人性别:");
scanf("%s", book->p[book->cur_size].sex);
printf("请输入联系人年龄:");
scanf("%d", &book->p[book->cur_size].age);//年龄属于数字,需用%d打印输出
printf("请输入联系人电话:");
scanf("%s", book->p[book->cur_size].phone);
printf("请输入联系人地址:");
scanf("%s", book->p[book->cur_size].address);
book->cur_size += 1;
return 0;
}
动态版本:
int book_add(struct address_book *book)
{
expansion(book);
printf("请输入联系人姓名:");
scanf("%s", book->p[book->cur_size].name);
printf("请输入联系人性别:");
scanf("%s", book->p[book->cur_size].sex);
printf("请输入联系人年龄:");
scanf("%d", &book->p[book->cur_size].age);//年龄属于数字,需用%d打印输出
printf("请输入联系人电话:");
scanf("%s", book->p[book->cur_size].phone);
printf("请输入联系人地址:");
scanf("%s", book->p[book->cur_size].address);
book->cur_size += 1;
return 0;
}
此模块中涉及检查通讯录容量部分,如果容量已超过最初设置的参数,则将扩容,将这部分也写成了一个函数如下所示:
核查通讯录容量
int expansion(struct address_book *book)
{
if (book->cur_size == book->capacity-1)
{
struct people_info *ptr = (struct people_info*)realloc(book->p, (book->capacity + 2) * sizeof(struct people_info));
if (ptr != NULL)
{
book->p = ptr;
book->capacity += 2;
printf("扩容成功\n");
}
else
{
perror("通讯录增容失败");
exit(1);
}
}
}
3.销毁通讯录
void book_destory(struct address_book *book)
{
book_saveaddress(book);
free(book->p);
book->p = NULL;
book->capacity = 0;
book->cur_size = 0;
}
4.显示所有联系人
void book_print(struct address_book *book)
{
printf("%10s\t%5s\t%5s\t%15s\t%20s\n", "姓名", "性别", "年龄", "电话", "地址");
for (int i = 0; i < book->cur_size; i++)
{
printf("%10s\t%5s\t%5d\t%15s\t%20s\n", book->p[i].name, book->p[i].sex, book->p[i].age, book->p[i].phone, book->p[i].address);
}
return;
}
5.显示单个联系人
void print_people(struct address_book *book, int i)//打印单个联系人
{
printf("%10s\t%5s\t%5s\t%15s\t%20s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%10s\t%5s\t%5d\t%15s\t%20s\n", book->p[i].name, book->p[i].sex, book->p[i].age, book->p[i].phone, book->p[i].address);
}
6.删除指定联系人
int book_del(struct address_book *book)
{
printf("请输入要删除的联系人名称:");
int pos = book_find(book);
if (pos == -1)
{
printf("要删除的联系人不存在!\n");
return -1;
}
for (int i = pos; i < book->cur_size - 1; i++)//i < book->cur_size - 1,防止i+1出现越界问题
{
book->p[i] = book->p[i + 1];
}
book->cur_size--;
printf("删除联系人完毕!\n");
return 0;
}
7.查找指定联系人
int book_find(struct address_book *book)
{
//printf("请输入要查找的联系人名称:");
char name[32] = { 0 };
scanf("%s", name);
for (int i = 0; i < book->cur_size; i++)
{
if (strcmp(name, book->p[i].name) == 0)//strcmp比较两个字符串
{
return i;
}
}
return 0;
}
int find(struct address_book *book)
{
printf("请输入要查找的联系人名称:");
int pos = book_find(book);
if (pos == -1)
{
printf("要查找的联系人不存在!\n");
return -1;
}
print_people(book, pos);
return 0;
}
8.修改指定联系人
int book_mod(struct address_book *book)
{
printf("请输入要修改的联系人名称:");
int pos = book_find(book);
if (pos == -1)
{
printf("要修改的联系人不存在!\n");
return -1;
}
printf("********修改信息选择**********\n");
printf("*****1.姓名 2.性别*****\n");
printf("*****3.年龄 4.电话*****\n");
printf("*****5.地址 0.退出*****\n");
printf("********修改信息选择**********\n");
int choice = -1;
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("请输入联系人姓名:");
scanf("%s", book->p[pos].name);
break;
case 2:
printf("请输入联系人性别:");
scanf("%s", book->p[pos].sex);
break;
case 3:
printf("请输入联系人年龄:");
scanf("%d", &book->p[pos].age);
break;
case 4:
printf("请输入联系人电话:");
scanf("%s", book->p[pos].phone);
break;
case 5:
printf("请输入联系人地址:");
scanf("%s", book->p[pos].address);
break;
default:
printf("退出修改!\n");
}
printf("修改完毕!\n");
return 0;
}
9.将所有联系人排序
int book_sort(struct address_book *book)
{
for (int i = 0; i < book->cur_size-1; i++)
{
for (int j = 0; j < book->cur_size - i - 1; j++)
{
if (strcmp(book->p[j].name, book->p[j + 1].name) > 0)
{
struct people_info tmp = book->p[j];
book->p[j] = book->p[j + 1];
book->p[j + 1] = tmp;
}
}
}
return 0;
}
10.将通讯录信息保存到文件中
void book_saveaddress(struct address_book *book)
{
FILE* pout = fopen("address_book.dat", "wb");//打开文件,二进制写
if (pout == NULL)
{
printf("打开失败\n");
return;
}
for (int i = 0; i < book->cur_size; i++)
{
fwrite(book->p + i, sizeof(struct people_info), 1, pout);
}
printf("保存成功\n");
fclose(pout);
pout = 0;
}