通讯录
静态版本
通讯录在我们日常生活中常见,它可以帮助我们记录信息那我们今天就来实现一下通讯录。
首先我们需要定义两个.c文件和一个.h文件
contact.h
声明和一些定义
contact.c
实现程序
main.c
主函数
需要在两个.c文件中包含"contact.h"
我们再来打印一个菜单,可以让我们选择操作
void menu()
{
printf("************************\n");
printf("*** 1.Add 2.Del ***\n");
printf("*** 3.Search ***\n");
printf("*** 4.Mod 5.Show ***\n");
printf("*** 6.Sore 0.Exit ***\n");
printf("************************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请输入:");
scanf("%d", &input);
switch (input)
{
case Exit:
printf("退出通讯录\n");
break;
case Add:
case Del:
case Search:
case Mod:
case Show:
case Sore:
default :
printf("选择错误\n");
}
} while (input);
return 0;
}
那么我们要录入信息,就先创建信息
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#define Max 100
#define Max_name 20
#define Max_sex 8
#define Max_tele 12
#define Max_addr 20
typedef struct Peoinfo
{
char name[Max_name];
int age;
char sex[Max_sex];
char tele[Max_tele];
char addr[Max_addr];
}Peoinfo;
typedef struct Contact
{
Peoinfo date[Max];
int sz;
}Contact;
enum
{
Exit,//0
Add,//1
Del,//2
Search,//3
Mod,//4
Show,//5
Sore//6
//结果分别是
};
一个人的信息有名字,年龄,性别,电话,地址
第二个是保存了多少人的信息
枚举了一些可能
首先我们把通讯录初始化
void contactInit(Contact* pc)
{
pc->sz = 0;
memset(pc->date, 0, sizeof(Peoinfo) * Max);
}
这样我们就成功初始化了通讯录
那么我们来实现第一个函数增加人的信息
void Addcontact(Contact* pc)
{
if (pc->sz == Max)
{
printf("通讯录已满\n");
}
else
{
printf("请输入姓名:");
scanf("%s", pc->date[pc->sz].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入性别:");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入电话:");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址:");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("增加联系人成功\n");
}
}
写到这里我们可以实现这些功能
接下来我们来打印这些数据
void Showcontact(Contact* pc)
{
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n","姓名","年龄","性别","电话","地址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n", pc->date[i].name,
pc->date[i].age,
pc->date[i].sex,
pc->date[i].tele,
pc->date[i].addr);
}
}
接下来我们实现删除人的信息
int Findname(Contact* pc, char name[20])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->date[i].name,name)==0)
{
return i;
}
}
return -1;
}
void Delcontact(Contact* pc)
{
char name[20];
printf("请输入要删除人的信息:");
scanf("%s", name);
int ret = Findname(pc,name);
if (ret == -1)
{
printf("要删除的人不存在\n");
}
else
{
int j = 0;
for (j = ret; j < pc->sz - 1; j++)
{
pc->date[j] = pc->date[j + 1];
}
printf("成功删除联系人\n");
}
}
定义一个函数判断是否相等,相等返回下标
那么我们来搜所人是否存在
void Searchcontact(Contact* pc)
{
char name[20];
printf("输入要搜索人的信息:");
scanf("%s", name);
int ret = Findname(pc, name);
if (ret == -1)
{
printf("要搜索的人不存在\n");
}
else
{
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n", pc->date[ret].name,
pc->date[ret].age,
pc->date[ret].sex,
pc->date[ret].tele,
pc->date[ret].addr);
}
}
那么怎么修改信息
void Modcontact(Contact* pc)
{
char name[20];
printf("请输入要修改人的姓名");
scanf("%s", name);
int ret = Findname(pc,name);
if (ret == -1)
{
printf("要修改的人不存在\n");
}
else
{
printf("请输入姓名:");
scanf("%s", pc->date[ret].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[ret].age));
printf("请输入性别:");
scanf("%s", pc->date[ret].sex);
printf("请输入电话:");
scanf("%s", pc->date[ret].tele);
printf("请输入地址:");
scanf("%s", pc->date[ret].addr);
printf("成功修改\n");
}
}
最后一个我们可以来排序,按照名字来排序
int com_name(const void* e1, const void* e2)
{
return strcmp(((Peoinfo*)e1)->name, ((Peoinfo*)e2)->name);
}
void Sorecontact(Contact* pc)
{
qsort(pc->date,pc->sz,sizeof(Peoinfo),com_name);
}
到这里我们的静态版本通讯录就完成了
动态版本
思想:静态版本是固定的容量,我们只用几个数据就浪费了很多空间
动态版本首先我们开辟一个3个空间的信息,不够了我们每次增加2个空间
那么首先增容就需要定义一个信息的地址,一直用那个地方增加容量
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Max 100
#define Max_name 20
#define Max_sex 8
#define Max_tele 12
#define Max_addr 20
#define INC_SZ 3//初识的容量
#define ADD_SZ 2//每次增加的容量
typedef struct Peoinfo
{
char name[Max_name];
int age;
char sex[Max_sex];
char tele[Max_tele];
char addr[Max_addr];
}Peoinfo;
typedef struct Contact
{
Peoinfo* date;
int sz;
int capaticy;
}Contact;
date是一个指针,每一个存放的都是Peoinfo的信息
初始化
void contactInit(Contact* pc)
{
pc->date= (Peoinfo*)malloc(sizeof(Peoinfo)* 3);
if (pc->date == NULL)
return;
pc->sz = 0;
pc->capaticy = INC_SZ;
}
其他的程序不改变,只需要改变增加人时要考虑的增容和退出时释放空间
我们首先看增容
int Findcapa(Contact* pc)
{
if (pc->capaticy == pc->sz)
{
Peoinfo* pf = (Peoinfo*)realloc(pc->date, (pc->capaticy + ADD_SZ)*sizeof(Peoinfo));
if (pf == NULL)
{
perror("Findcapa");
return -1;
}
else
{
pc->date = pf;
pc->capaticy += ADD_SZ;
printf("增容成功\n");
return 1;
}
}
return 1;
}
void Addcontact(Contact* pc)
{
int ret=Findcapa(pc);
if (ret == -1)
{
printf("增容失败\n");
return;
}
else
{
printf("请输入姓名:");
scanf("%s", pc->date[pc->sz].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入性别:");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入电话:");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址:");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("增加联系人成功\n");
}
}
定义一个函数来增容
那么我们在退出的时候需要释放掉空间
void exitcontact(Contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->capaticy = 0;
pc->sz = 0;
}
文件版本
思想:退出通讯录的时候需要把数据保存到文件中,再次打开,需要把文件中的数据放在我们的程序中。
需要改变的是退出通讯录时把信息保存到文件中,打开文件时,把文件的信息放到我们的程序中
那么我们来实现退出通讯录时保存信息到文件中
void Savecontact(Contact* pc)
{
FILE* pfw=fopen("data.txt", "wb");
if (pfw == NULL)
{
perror("Savecontact::fopen");
return;
}
for (int i = 0; i < pc->sz; i++)
{
fwrite(pc->date + i, sizeof(Peoinfo), 1, pfw);
}
fclose(pfw);
pfw = NULL;
}
我们在创建文件下找到我们的文件
打开后是用二进制储存的
接下来就需要我们在打开文件时把文件的信息放到程序中
我们在初始化时就需我们把文件中的信息放到程序中我们来实现
void openfile(Contact* pc)
{
FILE* pfr = fopen("data.txt", "rb");
if (pfr == NULL)
{
perror("openfile::fopen");
return;
}
Peoinfo tmp = { 0 };
while (fread(&tmp, sizeof(Peoinfo), 1, pfr))
{
Findcapa(pc);
pc->date[pc->sz] = tmp;
pc->sz++;
}
fclose(pfr);
pfr = NULL;
}
void contactInit(Contact* pc)
{
pc->date = (Peoinfo*)malloc(sizeof(Peoinfo)* 3);
if (pc->date == NULL)
return;
pc->sz = 0;
pc->capaticy = INC_SZ;
openfile(pc);
}
我们直接就能把文件中的数据打印出来
contact.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Max 100
#define Max_name 20
#define Max_sex 8
#define Max_tele 12
#define Max_addr 20
#define INC_SZ 3//初识的容量
#define ADD_SZ 2//每次增加的容量
typedef struct Peoinfo
{
char name[Max_name];
int age;
char sex[Max_sex];
char tele[Max_tele];
char addr[Max_addr];
}Peoinfo;
typedef struct Contact
{
Peoinfo* date;
int sz;
int capaticy;
}Contact;
//typedef struct Contact
//{
// Peoinfo date[Max];
// int sz;
//}Contact;
enum
{
Exit,
Add,
Del,
Search,
Mod,
Show,
Sore
};
//初始化通讯录
void contactInit(Contact* pc);
//增加人的信息
void Addcontact(Contact* pc);
//展示信息
void Showcontact(Contact* pc);
//删除人的信息
void Delcontact(Contact* pc);
//搜索人的信息是否存在
void Searchcontact(Contact* pc);
//修改人的信息
void Modcontact(Contact* pc);
//名字排序
void Sorecontact(Contact* pc);
//退出通讯录
void exitcontact(Contact* pc);
//保存信息
void Savecontact(Contact* pc);
contact.c
#include"contact.h"
//void contactInit(Contact* pc)
//{
// pc->sz = 0;
// memset(pc->date, 0, sizeof(Peoinfo) * Max);
//}
//void contactInit(Contact* pc)
//{
// pc->date= (Peoinfo*)malloc(sizeof(Peoinfo)* 3);
// if (pc->date == NULL)
// return;
// pc->sz = 0;
// pc->capaticy = INC_SZ;
//}
int Findcapa(Contact* pc);
void openfile(Contact* pc)
{
FILE* pfr = fopen("data.txt", "rb");
if (pfr == NULL)
{
perror("openfile::fopen");
return;
}
Peoinfo tmp = { 0 };
while (fread(&tmp, sizeof(Peoinfo), 1, pfr))
{
Findcapa(pc);
pc->date[pc->sz] = tmp;
pc->sz++;
}
fclose(pfr);
pfr = NULL;
}
void contactInit(Contact* pc)
{
pc->date = (Peoinfo*)malloc(sizeof(Peoinfo)* 3);
if (pc->date == NULL)
return;
pc->sz = 0;
pc->capaticy = INC_SZ;
openfile(pc);
}
int Findcapa(Contact* pc)
{
if (pc->capaticy == pc->sz)
{
Peoinfo* pf = (Peoinfo*)realloc(pc->date, (pc->capaticy + ADD_SZ)*sizeof(Peoinfo));
if (pf == NULL)
{
perror("Findcapa");
return -1;
}
else
{
pc->date = pf;
pc->capaticy += ADD_SZ;
printf("增容成功\n");
return 1;
}
}
return 1;
}
void Addcontact(Contact* pc)
{
int ret=Findcapa(pc);
if (ret == -1)
{
printf("增容失败\n");
return;
}
else
{
printf("请输入姓名:");
scanf("%s", pc->date[pc->sz].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入性别:");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入电话:");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址:");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("增加联系人成功\n");
}
}
//void Addcontact(Contact* pc)
//{
// if (pc->sz == Max)
// {
// printf("通讯录已满\n");
// }
// else
// {
// printf("请输入姓名:");
// scanf("%s", pc->date[pc->sz].name);
// printf("请输入年龄:");
// scanf("%d", &(pc->date[pc->sz].age));
// printf("请输入性别:");
// scanf("%s", pc->date[pc->sz].sex);
// printf("请输入电话:");
// scanf("%s", pc->date[pc->sz].tele);
// printf("请输入地址:");
// scanf("%s", pc->date[pc->sz].addr);
//
// pc->sz++;
// printf("增加联系人成功\n");
// }
//}
void Showcontact(Contact* pc)
{
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n","姓名","年龄","性别","电话","地址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n", pc->date[i].name,
pc->date[i].age,
pc->date[i].sex,
pc->date[i].tele,
pc->date[i].addr);
}
}
int Findname(Contact* pc, char name[20])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->date[i].name,name)==0)
{
return i;
}
}
return -1;
}
void Delcontact(Contact* pc)
{
char name[20];
printf("请输入要删除人的信息:");
scanf("%s", name);
int ret = Findname(pc,name);
if (ret == -1)
{
printf("要删除的人不存在\n");
}
else
{
int j = 0;
for (j = ret; j < pc->sz - 1; j++)
{
pc->date[j] = pc->date[j + 1];
}
printf("成功删除联系人\n");
}
}
void Searchcontact(Contact* pc)
{
char name[20];
printf("输入要搜索人的信息:");
scanf("%s", name);
int ret = Findname(pc, name);
if (ret == -1)
{
printf("要搜索的人不存在\n");
}
else
{
printf("%-20s\t%-5s\t%-8s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-8s\t%-12s\t%-20s\n", pc->date[ret].name,
pc->date[ret].age,
pc->date[ret].sex,
pc->date[ret].tele,
pc->date[ret].addr);
}
}
void Modcontact(Contact* pc)
{
char name[20];
printf("请输入要修改人的姓名");
scanf("%s", name);
int ret = Findname(pc,name);
if (ret == -1)
{
printf("要修改的人不存在\n");
}
else
{
printf("请输入姓名:");
scanf("%s", pc->date[ret].name);
printf("请输入年龄:");
scanf("%d", &(pc->date[ret].age));
printf("请输入性别:");
scanf("%s", pc->date[ret].sex);
printf("请输入电话:");
scanf("%s", pc->date[ret].tele);
printf("请输入地址:");
scanf("%s", pc->date[ret].addr);
printf("成功修改\n");
}
}
int com_name(const void* e1, const void* e2)
{
return strcmp(((Peoinfo*)e1)->name, ((Peoinfo*)e2)->name);
}
void Sorecontact(Contact* pc)
{
qsort(pc->date,pc->sz,sizeof(Peoinfo),com_name);
}
void exitcontact(Contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->capaticy = 0;
pc->sz = 0;
}
void Savecontact(Contact* pc)
{
FILE* pfw=fopen("data.txt", "wb");
if (pfw == NULL)
{
perror("Savecontact::fopen");
return;
}
for (int i = 0; i < pc->sz; i++)
{
fwrite(pc->date + i, sizeof(Peoinfo), 1, pfw);
}
fclose(pfw);
pfw = NULL;
}
main.c
#include"contact.h"
void menu()
{
printf("************************\n");
printf("*** 1.Add 2.Del ***\n");
printf("*** 3.Search ***\n");
printf("*** 4.Mod 5.Show ***\n");
printf("*** 6.Sore 0.Exit ***\n");
printf("************************\n");
}
int main()
{
int input = 0;
Contact c;
contactInit(&c);
do
{
menu();
printf("请输入:");
scanf("%d", &input);
switch (input)
{
case Exit:
Savecontact(&c);
printf("保存成功\n");
exitcontact(&c);
printf("退出通讯录\n");
break;
case Add:
Addcontact(&c);
break;
case Del:
Delcontact(&c);
break;
case Search:
Searchcontact(&c);
break;
case Mod:
Modcontact(&c);
break;
case Show:
Showcontact(&c);
break;
case Sore:
Sorecontact(&c);
break;
default :
printf("选择错误\n");
}
} while (input);
return 0;
}
这就是全部的代码我们来展示一遍
(要退出时才会保存切记),我刚才就忘记退出了
谢谢你的观看!!!