近代通信少不了电话号码,但是朋友或是要联络的人太多,就需要把电话号码记下来,然而书本纸面上的记载,查询都太过麻烦,因此我们可以利用计算机编程实现一个多功能全面的通讯录,帮助我们更加方便的处理这些电话号码。
目标功能涵盖:
共需完成三种版本:
1.抽象个人信息
typedef struct PersonInfo
{
char name[MAX_NAME];
char sex[SEX_NAME];
short age;
char tele[TEL_NAME];
char addr[TEL_NAME];
}PersonInfo;
2.抽象通讯录
typedef struct Contact {
//PersonInfo per[MAX_PER_NUM] ;静态版本
int usedsize;//有效数据个数 动态版本
PersonInfo* per; //动态版本
int capacity;//初始容量
}Contact;//通讯录
需要实现函数:
#ifndef __CONTACT_H__
#define __CONTACT_H__
#include
#include
#include
#include
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MONDIFY,
SHOW,
EMPTY,
SORT
};
#define MAX_NAME 20
#define SEX_NAME 5
#define TEL_NAME 12
#define ADDR_NAME 20 //通讯录最多为1000人
#define MAX_PER_NUM 1000 //动态扩容版本
#define DEFAULT_SIZE 2;
typedef struct PersonInfo
{
char name[MAX_NAME];
char sex[SEX_NAME];
short age;
char tele[TEL_NAME];
char addr[TEL_NAME];
}PersonInfo;
typedef struct Contact
{
//PersonInfo per[MAX_PER_NUM] ;普通版本
PersonInfo* per;
int usedsize;//有效数据个数
int capacity;//初始容量
}Contact;//通讯录
//初始化通讯录
void InitContact(Contact *con);
//添加成员
void AddContact(Contact *con);
//打印通讯录
void ShowContact(Contact *con);
//删除成员
void DelContact(Contact *con);
//查找成员
int SearchContact(Contact *con);
//清空通讯录
void EmptyContact(Contact *con);
//摧毁通讯录(动态版本)
void DestoryContact(Contact *con);
//文件版本 //保存联系人到文件
void SaveContact(Contact *con);
//加载联系人
void LoadContact(Contact *con);
#endif //__CONTACT_H__
#include"contact.h"
void menu() {
printf("******************通讯录********************\n");
printf("*** 1.add 2.show 3.delete 4.search ****\n");
printf("*** 5.empty 6.distory 7.save 8.load ****\n");
printf("***************** 0.quit *******************\n");
printf("********************************************\n");
}
int main()
{
int select = 0;
Contact contact;
InitContact(&contact);
do{
menu();
printf("Pleas intput you changce:");
scanf("%d", &select);
switch (select)
{
case QUIT:
printf("Good bye!\n");
break;
case ADD:
AddContact(&contact);
break;
case SHOW:
ShowContact(&contact);
break;
case DEL:
DelContact(&contact);
break;
case SEARCH:
SearchContact(&contact);
break;
case EMPTY:
EmptyContact(&contact);
break;
case DESTORY:
DestoryContact(&contact);
break;
case SAVE:
SaveContact(&contact);
break;
case LOAD:
LoadContact(&contact);
break;
default:
break;
}
} while (select);
system("pause");
return 0;
}
void InitContact(Contact *pcon) {
//普通版本
//pcon->usedSize = 0;
//memset(pcon->per,0,sizeof(pcon->per));
pcon->usedsize = 0;
pcon->capacity = DEFAULT_SIZE;
pcon->per = (PersonInfo *)malloc(
sizeof(PersonInfo) * pcon->capacity);
assert(pcon->per != NULL);
LoadContact(pcon);//有可能文件中也有存储的联系人
}
void LoadContact(Contact *pcon) {
FILE *pf = fopen("Contact.bat", "rb");
PersonInfo tmp = { 0 };
if (pf == NULL)
{
return;
}
//fread函数的返回值是:读取成功的字节数
while (fread(&tmp, sizeof(PersonInfo), 1, pf) > 0)
{
//必须判断是否为满,如果满了扩容
CheckFullAndRe(pcon);
pcon->per[pcon->usedsize++] = tmp;
}
fclose(pf);
pf = NULL;
}
void AddContact(Contact *pcon) {
//普通版本,无扩容解决办法
//if(pcon->usedSize == MAX_NUMBER)
//{
// printf("this contact is full\n");
// return;
//}
if (CheckFullAndRe(pcon) != 1)
{
printf("扩容失败\n");
return;
}
printf("请输入姓名:");
scanf("%s", pcon->per[pcon->usedsize].name);
printf("请输入年龄:");
scanf("%d", &(pcon->per[pcon->usedsize].age));
printf("请输入性别:");
scanf("%s", pcon->per[pcon->usedsize].sex);
printf("请输入电话:");
scanf("%s", pcon->per[pcon->usedsize].tele);
printf("请输入住址:");
scanf("%s", pcon->per[pcon->usedsize].addr);
pcon->usedsize++;
printf("添加成功\n");
}
void ShowContact(Contact *pcon) {
int i = 0;
printf("%-10s %-5s %-5s %-11s %-20s\n", "姓名", "年龄",
"性别", "电话", "住址");
for (i = 0; i < pcon->usedsize; i++)
{
printf("%-10s %-5d %-5s %-11s %-20s\n",
pcon->per[i].name, pcon->per[i].age,
pcon->per[i].sex, pcon->per[i].tele,
pcon->per[i].addr);
}
}
void DelContact(Contact *pcon) {
int index = SearchContact(pcon);
int i = 0;
if (index == -1)
{
printf("删除失败,查无此人\n");
return;
}
for (i = index; i < pcon->usedsize - 1; i++)
{
pcon->per[i] = pcon->per[i + 1];
}
pcon->usedsize--;
printf("删除成功\n");
}
int SearchContact(Contact *pcon) {
int i = 0;
char name[MAX_NAME] = { 0 };
if (pcon->usedsize == 0)
{
printf("通讯录为空\n");
return -1;
}
printf("请输入你要删除的姓名:");
scanf("%s", name);
for (i = 0; i < pcon->usedsize; i++)
{
if (strcmp(pcon->per[i].name, name) == 0)
{
return i;
}
}
return -1;
}
void EmptyContact(Contact *pcon) {
pcon->usedsize = 0;
}
void DestoryContact(Contact *pcon) {
SaveContact(pcon);
free(pcon->per);
pcon->per = NULL;//预防野指针
pcon->capacity = 0;
pcon->usedsize = 0;
}
void SaveContact(Contact *pcon) {
int i = 0;
FILE *pf = fopen("Contact.bat", "wb");
assert(pf != NULL);
for (i = 0; i < pcon->usedsize; i++)
{
fwrite(pcon->per + i, sizeof(PersonInfo), 1, pf);
}
fclose(pf);
pf = NULL;
}
通讯录无论是静态版本还是动态版本,储存人数都有上限。
动态内存虽然可以需要多少开辟多少内存,但仍需要在编程中定义。
设计一个拓展函数,如果存储不足时,再开辟更多内存。
扩容通讯录
static int CheckFullAndRe(Contact *pcon) {
if (pcon->usedsize == pcon->capacity)
{
PersonInfo * ptr = NULL;
ptr = (PersonInfo *)realloc(pcon->per,
sizeof(PersonInfo) * pcon->capacity * 2);
if (ptr != NULL)
{
pcon->per = ptr;
pcon->capacity *= 2;
printf("扩容成功\n");
return 1;
}
else
{
return 0;//扩容失败
}
}
return 1;
}
我的通讯录项目源码:https://github.com/GagaAutom/C-programming-language/blob/master/my_contact/contact