MailList.h文件
#ifndef __MAILLIST__H__
#define __MAILLIST__H__
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <assert.h>
#define M 10 //通讯录默认大小,即默认存储10个人
#define N 5 //扩大/缩小一次通讯录容量的大小
struct Person//个人信息
{
char Name[20];
char Sex[4];
int Age;
int PhoneNumber;
char Address[40];
};
struct MailList//通讯录(数组)
{
int EP; //已有人数:Existing Population
int MP; //当前最大存储人数
struct Person *person;
}ML;//(通讯录)结构体指针,用于接收动态分配的空间地址
//////////////////////////////////////////////////////
void InitMailList();//初始化函数
void Expand();//扩大通讯录容量
void Reduce();//缩小通讯录容量
void Release();//释放动态申请的空间
/////////////////////////////////////////////////////
void AddPerson(struct Person *person);//添加联系人
void ShowPerson(struct Person *person);//显示联系人
void InitPerson(struct Person *person);//初始化通讯录
int FindPerson(struct Person *person);//查找联系人,返回其下标
void SearchPerson(struct Person *person);//查找联系人,打印其信息
void DeletePerson(struct Person *person);//删除联系人
void ModifyPerson(struct Person *person);//修改联系人
void EmptyPerson(struct Person *person);//情况通讯录
void SortPerson(struct Person *person);//排序联系人
/////////////////////////////////////////////////////
void Save();//保存(写入)文件
void Load();//加载(读入)文件
#endif//__MAILLIST__H__
MailList.c文件
#define _CRT_SECURE_NO_WARNINGS -1
#include "MailList.h"
void InitMailList()//初始化函数
{
ML.EP = 0;
ML.MP = M;
ML.person = (struct Person *)malloc(sizeof(struct Person)*M);//动态分配默认大小的空间,即10个struct Person类的大小
if (ML.person == NULL)//动态申请空间失败
{
perror("malloc");
return;
}
memset(ML.person, 0, sizeof(struct Person)*M);//将通讯录全部初始化为0
}
void Expand()//扩大通讯录容量
{
struct Person * tmp = (struct Person *)realloc(ML.person, sizeof(struct Person)*(ML.MP + N));
//重新定义一个指针接收realloc分配的空间地址,而不是直接用原空间指针接收
//是为了防止出现申请空间失败返回NULL导致原空间指针被置NULL
if (tmp == NULL)//动态申请空间失败
{
perror("malloc");
return;
}
ML.person = tmp;
ML.MP += N;//当前最大容量增加N
}
void Reduce()//缩小通讯录容量
{
if (ML.EP > (ML.MP - N) || 0 >= (ML.MP - N))//如果缩小后的空间不足以存储当前人数或缩小后的空间小于等于0
{
printf("通讯录容量不足以缩小!\n");
return;
}
struct Person * tmp = (struct Person *)realloc(ML.person, sizeof(struct Person)*(ML.MP - N));
if (tmp == NULL)//动态申请空间失败
{
perror("malloc");
return;
}
ML.person = tmp;
ML.MP -= N;//当前最大容量减少N
}
void ShowPerson(struct Person *person)//显示联系人信息
{
assert(person);
if (0 == ML.EP)
{
printf("通讯录为空!\n");
return;
}
int i = 0;
for (i = 0; i < ML.EP; i++)
{
printf("%s ", person[i].Name);
printf("%s ", person[i].Sex);
printf("%d ", person[i].Age);
printf("%d ", person[i].PhoneNumber);
printf("%s ", person[i].Address);
printf("\n");
}
}
void Release()//释放动态申请的空间
{
if (ML.person!=NULL)
{
free(ML.person);
}
ML.person = NULL;
}
void AddPerson(struct Person *person)//添加联系人信息
{
assert(person);
if (ML.EP == ML.MP)
{
printf("通讯录已满!\n");
return;
}
printf("输入名字:>\n");
scanf("%s", &person[ML.EP].Name);
printf("输入性别:>\n");
scanf("%s", &person[ML.EP].Sex);
printf("输入年龄:>\n");
scanf("%d", &person[ML.EP].Age);
printf("输入手机号:>\n");
scanf("%d", &person[ML.EP].PhoneNumber);
printf("输入地址:>\n");
scanf("%s", &person[ML.EP].Address);
ML.EP++; //已添加人数加一
}
int FindPerson(struct Person *person)//按名字查找联系人信息,返回其下标
{
assert(person);
int i = 0;
printf("请输入姓名:>");
char name[10] = { 0 };
scanf("%s", name);
for (i = 0; i < ML.EP; i++)
{
if (0 == strcmp(person[i].Name, name))
{
return i;
}
}
printf("不存在该联系人!\n");
return -1;
}
void SearchPerson(struct Person *person)//按名字查找联系人信息,打印其信息
{
assert(person);
int i = FindPerson(person);
if (i >= 0)
{
printf("%s ", person[i].Name);
printf("%s ", person[i].Sex);
printf("%d ", person[i].Age);
printf("%d ", person[i].PhoneNumber);
printf("%s ", person[i].Address);
printf("\n");
}
}
void DeletePerson(struct Person *person)//删除指定姓名的联系人信息
{
assert(person);
int i = 0;
int ret = 0;
ret = FindPerson(person);
if (ret == ML.EP - 1)//恰好删除最后一个
{
ML.EP--;
}
else if (ret >= 0 && ret<ML.EP)
{
person[ret] = person[ML.EP - 1];
ML.EP--;
}
}
void ModifyPerson(struct Person *person)//修改联系人信息
{
assert(person);
int ret = 0;
ret = FindPerson(person);
if (ret >= 0)
{
printf("输入名字:>\n");
scanf("%s", &person[ret].Name);
printf("输入性别:>\n");
scanf("%s", &person[ret].Sex);
printf("输入年龄:>\n");
scanf("%d", &person[ret].Age);
printf("输入手机号:>\n");
scanf("%d", &person[ret].PhoneNumber);
printf("输入地址:>\n");
scanf("%s", &person[ret].Address);
}
}
void EmptyPerson(struct Person *person)//清空通讯录
{
assert(person);
ML.EP = 0;
}
void SortPerson(struct Person *person)//按名字排序通讯录
{
assert(person);
int i = 0;
int j = 0;
for (i = 0; i < ML.EP - 1; i++)
for (j = 0; j < ML.EP - 1 - i; j++)
{
if (strcmp(person[j].Name, person[j + 1].Name)>0)
{
struct Person p = person[j];
person[j] = person[j + 1];
person[j + 1] = p;
}
}
}
void Save()//保存(写入)文件
{
int i = 0;
FILE *pfw = fopen("MailList.txt", "w");//按"写"的方式打开文件
if (pfw == NULL)//打开文件失败
{
perror("open file for write");
exit(1);//(错误)退出程序
}
for (i = 0; i<ML.EP; i++)//将键入内容写入到文件中
{
fwrite(&(ML.person[i]), sizeof(struct Person), 1, pfw);
}
fclose(pfw);
}
void Load()//加载(读入)文件
{
int i = 0;
struct Person tmp = { 0 };
FILE *pfr = fopen("MailList.txt", "r");//按"读"的方式打开文件
if (pfr == NULL)//打开文件失败
{
perror("open file for read");
exit(1);//(错误)退出程序
}
fread(&tmp, sizeof(struct Person), 1, pfr);
while (!feof(pfr))//当未读到文件结尾时
{
if (ML.EP == ML.MP)//当前人数达到最大容量时
{
Expand();//扩大容量
}
ML.person[i] = tmp;
i++;
ML.EP++;
fread(&tmp, sizeof(struct Person), 1, pfr);
}
}
test.c文件
#define _CRT_SECURE_NO_WARNINGS -1
#include "MailList.h"
void menu()
{
printf("\n");
printf("*******************************************\n");
printf("************ My Mail List ***************\n");
printf("**** 1-添加 2-删除 3-查找 ****\n");
printf("**** 4-清空 5-修改 6-排序 ****\n");
printf("**** 7-显示 8-扩充 9-缩减 ****\n");
printf("****10-加载 0-退出 ****\n");
printf("*******************************************\n");
printf("\n");
}
void test()
{
int num = 0;
InitMailList();
while (1)
{
menu();
printf("请选择:>");
scanf("%d", &num);
switch (num)
{
case 1:
AddPerson(ML.person);
break;
case 2:
DeletePerson(ML.person);
break;
case 3:
SearchPerson(ML.person);
break;
case 4:
EmptyPerson(ML.person);
break;
case 5:
ModifyPerson(ML.person);
break;
case 6:
SortPerson(ML.person);
break;
case 7:
ShowPerson(ML.person);
break;
case 8:
Expand();
break;
case 9:
Reduce();
break;
case 10:
Load();
break;
case 0:
{
Save();
Release();
return;
}
break;
default:
break;
}
}
}
int main()
{
test();
system("pause");
return 0;
}
关于feofs()的使用细节,可参照链接:fhttp://blog.csdn.net/a1066570234/article/details/78653862