目录
前言
通讯录用来存储联系人信息:名字,性别,年龄,电话,地址。
基本功能:1.添加联系人信息 2.删除联系人信息 3.查找联系人 4.修改联系人信息
5.打印信息 6.按照名字对联系人进行排序。
构造框架
首先创建菜单,再建立框架,将菜单和功能联系起来。
void menu()
{
printf("**************************************\n");
printf("********1.ADD 2.Delete*******\n");
printf("********3.Search 4.Modify*******\n");
printf("********5.Print 6.Sort*********\n");
printf("******** 0.exit ********\n");
printf("**************************************\n");
}
void test()
{
contact c1;
Init(&c1);
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
Add(&c1);
break;
case 2:
Delete(&c1);
break;
case 3:
Search(&c1);
break;
case 4:
Modify(&c1);
break;
case 5:
Print(&c1);
break;
case 6:
Sort_byname(&c1);
break;
case 0:
SaveContact(&c1);//保留数据
Destory(&c1);
break;
default:
printf("输入非法,请重新输入\n");
break;
}
} while (input);
}
接下来构造结构体。
typedef struct Private //联系人信息
{
char name[20];//名字
char sex[5];//性别
int age;//年龄
char phone[15];//电话
char address[20];//地址
}Private;
typedef struct contact//通讯录
{
Private* data;
int size;//已存联系人个数
int capacity;//容量
}contact;
功能实现
Init
初始化过程要把文件中的信息读取到通讯录。在读取过程中,若空间已满则要开辟新的空间。
总结初始化分为两步:检查空间和加载信息。
检查空间
void check(contact* c1)//检查是否满
{
assert(c1);
if (c1->size == c1->capacity)
{
Private* tmp = (Private*)realloc(c1->data, sizeof(Private)*(c1->capacity + 2));
if (tmp == NULL)
{
printf("扩容失败\n");
return;
}
c1->data = tmp;
c1->capacity += 2;
printf("增容成功\n");
}
}
加载信息
void LoadContact(contact* c1)//加载信息到通讯录
{
assert(c1);
//打开文件
FILE* pf = fopen("contact.txt", "rb");//以二进制读方式打开
if (pf == NULL)
{
perror("open:");//打印错误信息
return;
}
//读入数据
while (fread(c1->data + (c1->size), sizeof(Private), 1, pf))
{
c1->size++;
check(c1);//检查元素是否溢出
}
//关闭文件
fclose(pf);
pf = NULL;
}
合并
void Init(contact* c1) //初始化
{
assert(c1);
c1->size = 0;
c1->capacity = 4;
Private* tmp = (Private*)malloc(sizeof(Private) * c1->capacity);
if (tmp == NULL)
{
printf("初始化失败");
return;
}
c1->data = tmp;
memset(c1->data, 0, sizeof(c1->data));
LoadContact(c1);//把文件信息加载到通讯录
}
Exit
退出通讯录时,要将通讯录中的信息存到文件中,并销毁通讯录。
分装成 SaveContact和Destory两个函数实现。
SaveContact
void SaveContact(contact* c1)
{
FILE* pf = fopen("contact.txt", "wb");//以二进制写形式保留数据
if (pf == NULL)
{
perror("OPEN:");
return;
}
//写入文件
for (int i = 0; i < c1->size; i++)
{
fwrite(c1->data + i, sizeof(Private), 1, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
}
Destory
void Destory(contact* c1)
{
assert(c1);
free(c1->data);
c1->data = NULL;
c1->capacity = c1->size = 0;
printf("销毁成功");
}
add
每次添加信息也要判断空间是否满。
void Add(contact* c1)
{
assert(c1);
check(c1);//检查通讯录是否满
printf("请输入添加人的姓名->");
scanf("%s", c1->data[c1->size].name);
printf("请输入添加人的性别->");
scanf("%s", c1->data[c1->size].sex);
printf("请输入添加人的年龄->");
scanf("%d", &c1->data[c1->size].age);
printf("请输入添加人的电话->");
scanf("%s", c1->data[c1->size].phone);
printf("请输入添加人的地址:->");
scanf("%s", c1->data[c1->size].address);
printf("添加成功\n");
c1->size++;
}
Delete
要删除一个联系人的信息,首先要检查这个联系人是否存在。所以这里要再实现一个按名查找功能。
int find_name(contact* c1,char *s)//找到联系人的位置
{
assert(c1);
for (int i = 0; i < c1->size; i++)
{
if (strcmp(s, c1->data[i].name) == 0)
{
return i;
}
}
return -1;
}
void Delete(contact* c1)
{
assert(c1);
if (c1->size == 0)
{
printf("通讯录已空,无法删除\n");
return;
}
char a[20] = { 0 };
printf("请输入要删除人的名字->");
scanf("%s", a);
int pos = find_name(c1,a);
if (pos == -1)
{
printf("没有该联系人,无法删除\n");
return;
}
else
{
for (int i = pos; i < c1->size-1; i++)
{
c1->data[i] = c1->data[i + 1];
}
}
printf("删除成功\n");
c1 ->size--;
}
Search
查找功能也要使用fine_name函数判断联系人是否存在。
void Search(contact* c1)
{
assert(c1);
char a[20] = { 0 };
printf("请输入要查找的人名字->");
scanf("%s", a);
int pos = find_name(c1, a);
if (pos == -1)
{
printf("无该联系人\n");
return;
}
else
{
printf("%-20s %-5s %-5s %-15s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s %-5s %-5d %-15s %-30s\n ", c1->data[pos].name,c1->data[pos].sex,c1->data[pos].age,c1->data[pos].phone,c1->data[pos].address);
}
}
Modify
修改联系人信息。
void Modify(contact* c1)
{
assert(c1);
char a[20] = { 0 };
printf("请输入要修改的人名字:");
scanf("%s", a);
int pos = find_name(c1, a);
if (pos == -1)
{
printf("无该联系人,无法修改\n");
return;
}
else
{
printf("请输入新姓名:");
scanf("%s", c1->data[pos].name);
printf("请输入新性别:");
scanf("%s", c1->data[pos].sex);
printf("请输入新年龄:");
scanf("%d", &c1->data[pos].age);
printf("请输入新电话:");
scanf("%s", c1->data[pos].phone);
printf("请输入新地址:");
scanf("%s", c1->data[pos].address);
printf("修改成功\n");
}
}
Sort_byname
这里按名排序功能,采用冒泡排序方式实现。
void Sort_byname(contact* c1)
{
assert(c1);
for (int i = 0; i < c1->size-1; i++)//冒泡排序
{
for (int j = 1; j <= c1->size - 1 - i; j++)
{
if (strcmp(c1->data[j - 1].name, c1->data[j].name)>0)
{
Private tmp = c1->data[j-1];
c1->data[j - 1] = c1->data[j];
c1->data[j] = tmp;
}
}
}
printf("排序成功\n");
}
将通讯录中所有联系人信息打印出来。
void Print(contact* c1)
{
assert(c1);
if (c1->size == 0)//先判断通讯录是否为空
{
printf("通讯录已空,无法打印\n");
return;
}
printf("%-30s %-5s %-5s %-15s %-30s\n", "姓名","性别","年龄","电话","地址");
for (int i = 0; i < c1->size; i++)
{
printf("%-30s %-5s %-5d %-15s %-30s\n", c1->data[i].name,c1->data[i].sex,c1->data[i].age,c1->data[i].phone,c1->data[i].address);
}
}
以上就是通讯录的实现过程了。
完整代码
contact.h
#include<assert.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS 1
typedef struct Private//个人信息
{
char name[20];//名字
char sex[5];//性别
int age;//年龄
char phone[15];//电话
char address[20];//地址
}Private;
typedef struct contact//通讯录
{
Private* data;
int size;//个数
int capacity;//容量
}contact;
int find_name(contact* c1, char* s);
void check(contact* c1);
void Init(contact* c1);
void Destory(contact* c1);
void Add(contact* c1);
void Delete(contact* c1);
void Search(contact* c1);
void Modify(contact* c1);
void Print(contact* c1);
void Sort_byname(contact* c1);
void SaveContact(contact* c1);
contact.c
#include"contact.h"
void LoadContact(contact* c1)
{
assert(c1);
//打开文件
FILE* pf = fopen("contact.txt", "rb");//以二进制读方式打开
if (pf == NULL)
{
perror("open:");//打印错误信息
return;
}
//读入数据
while (fread(c1->data + (c1->size), sizeof(Private), 1, pf))
{
c1->size++;
check(c1);//检查元素是否溢出
}
//关闭文件
fclose(pf);
pf = NULL;
}
void Init(contact* c1) //初始化
{
assert(c1);
c1->size = 0;
c1->capacity = 4;
Private* tmp = (Private*)malloc(sizeof(Private) * c1->capacity);
if (tmp == NULL)
{
printf("初始化失败");
return;
}
c1->data = tmp;
memset(c1->data, 0, sizeof(c1->data));
LoadContact(c1);//把文件信息加载到通讯录
}
void Destory(contact* c1)
{
assert(c1);
free(c1->data);
c1->data = NULL;
c1->capacity = c1->size = 0;
printf("销毁成功");
}
void check(contact* c1)//检查是否满
{
assert(c1);
if (c1->size == c1->capacity)
{
Private* tmp = (Private*)realloc(c1->data, sizeof(Private)*(c1->capacity + 2));
if (tmp == NULL)
{
printf("扩容失败\n");
return;
}
c1->data = tmp;
c1->capacity += 2;
printf("增容成功\n");
}
}
void Add(contact* c1)
{
assert(c1);
check(c1);//检查通讯录是否满
printf("请输入添加人的姓名->");
scanf("%s", c1->data[c1->size].name);
printf("请输入添加人的性别->");
scanf("%s", c1->data[c1->size].sex);
printf("请输入添加人的年龄->");
scanf("%d", &c1->data[c1->size].age);
printf("请输入添加人的电话->");
scanf("%s", c1->data[c1->size].phone);
printf("请输入添加人的地址:->");
scanf("%s", c1->data[c1->size].address);
printf("添加成功\n");
c1->size++;
}
void Print(contact* c1)
{
assert(c1);
if (c1->size == 0)
{
printf("通讯录已空,无法打印\n");
return;
}
printf("%-30s %-5s %-5s %-15s %-30s\n", "姓名","性别","年龄","电话","地址");
for (int i = 0; i < c1->size; i++)
{
printf("%-30s %-5s %-5d %-15s %-30s\n", c1->data[i].name,c1->data[i].sex,c1->data[i].age,c1->data[i].phone,c1->data[i].address);
}
}
int find_name(contact* c1,char *s)//找到联系人的位置
{
assert(c1);
for (int i = 0; i < c1->size; i++)
{
if (strcmp(s, c1->data[i].name) == 0)
{
return i;
}
}
return -1;
}
void Delete(contact* c1)
{
assert(c1);
if (c1->size == 0)
{
printf("通讯录已空,无法删除\n");
return;
}
char a[20] = { 0 };
printf("请输入要删除人的名字->");
scanf("%s", a);
int pos = find_name(c1,a);
if (pos == -1)
{
printf("没有该联系人,无法删除\n");
return;
}
else
{
for (int i = pos; i < c1->size-1; i++)
{
c1->data[i] = c1->data[i + 1];
}
}
printf("删除成功\n");
c1 ->size--;
}
void Search(contact* c1)
{
assert(c1);
char a[20] = { 0 };
printf("请输入要查找的人名字->");
scanf("%s", a);
int pos = find_name(c1, a);
if (pos == -1)
{
printf("无该联系人\n");
return;
}
else
{
printf("%-20s %-5s %-5s %-15s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s %-5s %-5d %-15s %-30s\n ", c1->data[pos].name,c1->data[pos].sex,c1->data[pos].age,c1->data[pos].phone,c1->data[pos].address);
}
}
void Modify(contact* c1)
{
assert(c1);
char a[20] = { 0 };
printf("请输入要修改的人名字:");
scanf("%s", a);
int pos = find_name(c1, a);
if (pos == -1)
{
printf("无该联系人,无法修改\n");
return;
}
else
{
printf("请输入新姓名:");
scanf("%s", c1->data[pos].name);
printf("请输入新性别:");
scanf("%s", c1->data[pos].sex);
printf("请输入新年龄:");
scanf("%d", &c1->data[pos].age);
printf("请输入新电话:");
scanf("%s", c1->data[pos].phone);
printf("请输入新地址:");
scanf("%s", c1->data[pos].address);
printf("修改成功\n");
}
}
void Sort_byname(contact* c1)
{
assert(c1);
for (int i = 0; i < c1->size-1; i++)
{
for (int j = 1; j <= c1->size - 1 - i; j++)
{
if (strcmp(c1->data[j - 1].name, c1->data[j].name)>0)
{
Private tmp = c1->data[j-1];
c1->data[j - 1] = c1->data[j];
c1->data[j] = tmp;
}
}
}
printf("排序成功\n");
}
void SaveContact(contact* c1)
{
FILE* pf = fopen("contact.txt", "wb");//以二进制写形式保留数据
if (pf == NULL)
{
perror("OPEN:");
return;
}
//写入文件
for (int i = 0; i < c1->size; i++)
{
fwrite(c1->data + i, sizeof(Private), 1, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
}
test.c
#include"contact.h"
void menu()
{
printf("**************************************\n");
printf("********1.ADD 2.Delete*******\n");
printf("********3.Search 4.Modify*******\n");
printf("********5.Print 6.Sort*********\n");
printf("******** 0.exit ********\n");
printf("**************************************\n");
}
void test()
{
contact c1;
Init(&c1);
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
Add(&c1);
break;
case 2:
Delete(&c1);
break;
case 3:
Search(&c1);
break;
case 4:
Modify(&c1);
break;
case 5:
Print(&c1);
break;
case 6:
Sort_byname(&c1);
break;
case 0:
SaveContact(&c1);//保留数据
Destory(&c1);
break;
default:
printf("输入非法,请重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
希望对你有所帮助。