文件版最重要的就是保存文件,和加载文件,当退出通讯录的时候,就把通讯录里的信息保存下来,当执行通讯录的时候就加载之前退出通讯录保存的文件。
主要用到了fread和fwrite函数。
fread()
C 库函数 **size_t fread(void ptr, size_t size, size_t nmemb, FILE stream) 从给定流 stream 读取数据到 ptr 所指向的数组中。
参数
- ptr – 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
- size – 这是要读取的每个元素的大小,以字节为单位。
- nmemb – 这是元素的个数,每个元素的大小为 size 字节。
- stream – 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
返回值
成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。
fwrite()
C 库函数 **size_t fwrite(const void ptr, size_t size, size_t nmemb, FILE stream) 把 ptr 所指向的数组中的数据写入到给定流 stream 中。
参数
- ptr – 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
- size – 这是要读取的每个元素的大小,以字节为单位。
- nmemb – 这是元素的个数,每个元素的大小为 size 字节。
- stream – 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
返回值
成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。
LoadContact函数
void LoadContact(Contact* c)
{
FILE* pf =fopen("data.txt", "rb"); //先以二进制写入模式打开文件,如果没有就创建一个
if (pf == NULL)
{
perror("LoadContact::fopen");
return;
}
struct Person tmp = {0}; //因为读取的数据要存到一个变量里,所以先创建一个
while (fread(&tmp, sizeof(Person), 1, pf))
{
if (c->size == c->capcity) //初始化的时候最大容量为3,如果保存数据大于3的话就要增容,所以还要增容
{
Person* tmp = (Person*)realloc(c->p, sizeof(Person) * c->capcity + 2);
if (tmp != NULL)
{
c->p = tmp;
c->capcity += 2;
}
}
c->p[c->size] = tmp;
c->size++;
}
fclose(pf); //关闭文件
pf = NULL;
}
SaveContact函数
void SaveContact(Contact* c)
{
FILE* pf = fopen("data.txt", "wb");//先以二进制读模式打开文件。
if (pf == NULL)
{
perror("SaveContact::fopen");
return;
}
for (int i = 0; i < c->size; i++)
{
fwrite(c->p+i, sizeof(Person), 1, pf);
}
fclose(pf);
pf = NULL;
}
首先先定义一个结构体Contact来存储通讯录里的每个成员
Person结构体就是通讯录里的联系人,里面包含
- name-名字
- addr-地址
- tele-电话
- sex-性别
- age-年龄
Contact结构体里面有
- Person* p-指针变量,用来指向动态开辟出来的内存
- size-当前联系人的个数
- capcity-通讯录的最大人数
typedef struct Person
{
char name[20];
char addr[30];
char tele[12];
char sex[5];
int age;
}Person;
typedef struct Contact
{
Person* p;
int size;
int capcity;
}Contact;
菜单
void menu()
{
printf("欢迎使用通讯录!\n");
printf("1.添加联系人信息\n");
printf("2.删除指定联系人信息\n");
printf("3.查找指定联系人信息\n");
printf("4.修改指定联系人信息\n");
printf("5.显示所有联系人信息\n");
printf("6.清空所有联系人\n");
printf("7.以名字排序所有联系人\n");
printf("0.退出通讯录\n");
}
初始化通讯录
void ContactInit(Contact* c)
{
Person* tmp = (Person*)malloc(sizeof(Person) * 3); //先开辟3个Person的空间
if (tmp != NULL)
{
c->p = tmp;
}
else
{
printf("开辟失败");
}
c->size = 0;
c->capcity = 3;
}
添加联系人
void AddPerson(Contact* c)
{
if (c->size == c->capcity) //当前人数和通讯录的最大人数一样的时候就增容
{
Person* tmp = (Person*)realloc(c->p,sizeof(Person) * ((c->capcity)+2));
if (tmp != NULL)
{
c->p = tmp;
c->capcity += 2;
}
else
{
printf("开辟失败");
}
}
assert(c);
printf("请输入他的名字: "); //这里是添加联系人
scanf("%s", c->p[c->size].name);
printf("\n");
printf("请输入电话号码: ");
scanf("%s", c->p[c->size].tele);
printf("\n");
printf("请输入地址: ");
scanf("%s", c->p[c->size].addr);
printf("\n");
printf("请输入年龄: ");
scanf("%d", &(c->p[c->size].age));
printf("\n");
printf("请输入性别: ");
scanf("%s", c->p[c->size].sex);
c->size++;
printf("添加成功");
Sleep(500);
system("cls");
}
删除联系人
void DelePerson(Contact* c)
{
assert(c);
assert(c->size);
char str[20] = {0}; //创建一个变量用来查找删除人的姓名
printf("请输入要删除人的名字> ");
scanf("%s", str);
for (int i = 0; i < c->size; i++) //for循环遍历
{
if (strcmp(str,c->p[i].name) == 0) //找到了的情况
{
for (int j = i; j < c->size; j++) //从前往后赋值
{
c->p[j] = c->p[j + 1];
}
c->size--; //当前人数减1
printf("删除成功!");
Sleep(500);
system("cls");
return;
}
}
printf("查无此人!"); //没找到的情况
Sleep(500);
system("cls");
return;
}
显示所有的联系人
void ShowPerson(Contact* c)
{
assert(c);
assert(c->size);
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
for (int i = 0; i < c->size; i++)
{
printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].tele , c->p[i].addr);
}
system("pause");
system("cls");
}
查找联系人
void SearchPerson(Contact* c)
{
assert(c);
assert(c->size);
char str[20] = { 0 };
printf("请输入要查找人的名字> ");
scanf("%s", str);
for (int i = 0; i < c->size; i++)
{
if (strcmp(str, c->p[i].name) == 0)
{
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].tele, c->p[i].addr);
system("pause");
system("cls");
return;
}
}
printf("查无此人!");
Sleep(500);
system("cls");
}
修改某个联系人
void ModifyPerson(Contact* c)
{
assert(c);
assert(c->size);
char str[20] = { 0 };
printf("请输入要修改人的名字> ");
scanf("%s", str);
for (int i = 0; i < c->size; i++) //开始遍历整个数组
{
if (strcmp(str, c->p[i].name) == 0) //找到了的情况
{
printf("请输入他的名字: ");
scanf("%s", c->p[i].name);
printf("\n");
printf("请输入电话号码: ");
scanf("%s", c->p[i].tele);
printf("\n");
printf("请输入地址: ");
scanf("%s", c->p[i].addr);
printf("\n");
printf("请输入年龄: ");
scanf("%d", &(c->p[i].age));
printf("\n");
printf("请输入性别: ");
scanf("%s", c->p[i].sex);
printf("修改成功");
Sleep(500);
system("cls");
return;
}
}
printf("查无此人!"); //没找到
Sleep(500);
system("cls");
}
销毁通讯录
void DestroyContact(Contact* c)
{
c->size = 0; //将当前人数设为0
c->capcity = 0; //将通讯录总人数设为0
free(c->p); //释放p指向的内融
c->p = NULL; //将p设为空
}
按人名排序
int Cmp_by_Name(const void* buf1, const void* buf2)
{
return strcmp(((Person*)buf1)->name, ((Person*)buf2)->name);
}
void ByNameSort(Contact* c)
{
assert(c);
assert(c->size);
qsort(c->p, c->size, sizeof(Person), Cmp_by_Name);
printf("排序成功!");
Sleep(500);
system("cls");
}
完整代码
#include<stdio.h>
#include<assert.h>
#include<windows.h>
#include<stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
typedef struct Person
{
char name[20];
char addr[30];
char tele[12];
char sex[5];
int age;
}Person;
typedef struct Contact
{
Person* p;
int size;
int capcity;
}Contact;
void menu()
{
printf("欢迎使用通讯录!\n");
printf("1.添加联系人信息\n");
printf("2.删除指定联系人信息\n");
printf("3.查找指定联系人信息\n");
printf("4.修改指定联系人信息\n");
printf("5.显示所有联系人信息\n");
printf("6.清空所有联系人\n");
printf("7.以名字排序所有联系人\n");
printf("0.退出通讯录\n");
}
void LoadContact(Contact* c)
{
FILE* pf =fopen("data.txt", "rb");
if (pf == NULL)
{
perror("LoadContact::fopen");
return;
}
struct Person tmp = {0};
while (fread(&tmp, sizeof(Person), 1, pf))
{
if (c->size == c->capcity)
{
Person* tmp = (Person*)realloc(c->p, sizeof(Person) * c->capcity + 2);
if (tmp != NULL)
{
c->p = tmp;
c->capcity += 2;
}
}
c->p[c->size] = tmp;
c->size++;
}
fclose(pf);
pf = NULL;
}
void ContactInit(Contact* c)
{
Person* tmp = (Person*)malloc(sizeof(Person) * 3);
if (tmp != NULL)
{
c->p = tmp;
}
else
{
printf("开辟失败");
}
c->size = 0;
c->capcity = 3;
LoadContact(c);
}
void AddPerson(Contact* c)
{
if (c->size == c->capcity)
{
Person* tmp = (Person*)realloc(c->p,sizeof(Person) * ((c->capcity)+2));
if (tmp != NULL)
{
c->p = tmp;
c->capcity += 2;
}
else
{
printf("开辟失败");
}
}
assert(c);
printf("请输入他的名字: ");
scanf("%s", c->p[c->size].name);
printf("\n");
printf("请输入电话号码: ");
scanf("%s", c->p[c->size].tele);
printf("\n");
printf("请输入地址: ");
scanf("%s", c->p[c->size].addr);
printf("\n");
printf("请输入年龄: ");
scanf("%d", &(c->p[c->size].age));
printf("\n");
printf("请输入性别: ");
scanf("%s", c->p[c->size].sex);
c->size++;
printf("添加成功");
Sleep(500);
system("cls");
}
void DelePerson(Contact* c)
{
assert(c);
assert(c->size);
char str[20] = {0};
printf("请输入要删除人的名字> ");
scanf("%s", str);
for (int i = 0; i < c->size; i++)
{
if (strcmp(str,c->p[i].name) == 0)
{
for (int j = i; j < c->size; j++)
{
c->p[j] = c->p[j + 1];
}
c->size--;
printf("删除成功!");
Sleep(500);
system("cls");
return;
}
}
printf("查无此人!");
Sleep(500);
system("cls");
return;
}
void ShowPerson(Contact* c)
{
assert(c);
assert(c->size);
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
for (int i = 0; i < c->size; i++)
{
printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].tele , c->p[i].addr);
}
system("pause");
system("cls");
}
void SearchPerson(Contact* c)
{
assert(c);
assert(c->size);
char str[20] = { 0 };
printf("请输入要查找人的名字> ");
scanf("%s", str);
for (int i = 0; i < c->size; i++)
{
if (strcmp(str, c->p[i].name) == 0)
{
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s\t%-5s\t%-5d\t%-12s\t%-30s\n", c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].tele, c->p[i].addr);
system("pause");
system("cls");
return;
}
}
printf("查无此人!");
Sleep(500);
system("cls");
}
void ModifyPerson(Contact* c)
{
assert(c);
assert(c->size);
char str[20] = { 0 };
printf("请输入要修改人的名字> ");
scanf("%s", str);
for (int i = 0; i < c->size; i++)
{
if (strcmp(str, c->p[i].name) == 0)
{
printf("请输入他的名字: ");
scanf("%s", c->p[i].name);
printf("\n");
printf("请输入电话号码: ");
scanf("%s", c->p[i].tele);
printf("\n");
printf("请输入地址: ");
scanf("%s", c->p[i].addr);
printf("\n");
printf("请输入年龄: ");
scanf("%d", &(c->p[i].age));
printf("\n");
printf("请输入性别: ");
scanf("%s", c->p[i].sex);
printf("修改成功");
Sleep(500);
system("cls");
return;
}
}
printf("查无此人!");
Sleep(500);
system("cls");
}
void DestoryContact(Contact* c)
{
c->size = 0;
c->capcity = 0;
free(c->p);
c->p = NULL;
}
int Cmp_by_Name(const void* buf1, const void* buf2)
{
return strcmp(((Person*)buf1)->name, ((Person*)buf2)->name);
}
void ByNameSort(Contact* c)
{
assert(c);
assert(c->size);
qsort(c->p, c->size, sizeof(Person), Cmp_by_Name);
printf("排序成功!");
Sleep(500);
system("cls");
}
void q_sort(int L, int R, int* arr)
{
if (L >= R)
{
return;
}
int left = L;
int right = R;
int first = *(arr + left);
while (left < right)
{
while (left < right && *(arr + right) > first)
{
right--;
}
if (left < right)
{
*(arr + left) = *(arr + right);
}
while (left < right && *(arr + left) < first)
{
left++;
}
if (left < right)
{
*(arr + right) = *(arr + left);
}
if (left == right)
{
*(arr + left) = first;
}
}
q_sort(L, right - 1, arr);
q_sort(right + 1, R, arr);
}
void SaveContact(Contact* c)
{
FILE* pf = fopen("data.txt", "wb");
if (pf == NULL)
{
perror("SaveContact::fopen");
return;
}
for (int i = 0; i < c->size; i++)
{
fwrite(c->p+i, sizeof(Person), 1, pf);
}
fclose(pf);
pf = NULL;
}
int main()
{
Contact c;
int n;
ContactInit(&c);
do
{
menu();
printf("请输入: ");
scanf_s("%d", &n);
switch (n)
{
case 1:
AddPerson(&c);
break;
case 2:
DelePerson(&c);
break;
case 3:
SearchPerson(&c);
break;
case 4:
ModifyPerson(&c);
break;
case 5:
ShowPerson(&c);
break;
case 6:
DestoryContact(&c);
break;
case 7:
ByNameSort(&c);
break;
case 0:
SaveContact(&c);
DestoryContact(&c);
break;
}
} while (n);
}