1.目录
这里我们需要制作一个目录供使用者选择,具体代码如下
void menu()
{
printf("**************************************\n");
printf("*****1.Add 2.Del***********\n");
printf("*****3.Alt 4.Find**********\n");
printf("*****5.Print 6.Sort**********\n");
printf("*****7.Empty 0.Exit**********\n");
printf("**************************************\n");
}
2.多次运行
我们在操作通讯录的时候,需要进行多次操作,所以我们设置一个多次运行的代码
int input;
Contact con = {0};
con.data = (PeoInfo*)malloc(sizeof(PeoInfo) * MAX);
if (con.data == NULL)
{
printf("开辟空间失败\n");
return -1;
}
InitContact(&con);
do
{
menu();
printf("请选择:>\n");
scanf("%d", &input);
switch (input)
{
case Add:
ADD(&con);
break;
case Del:
Del_Con(&con);
break;
case Alt:
Alt_Con(&con);
break;
case Find:
Find_Con(&con);
break;
case Print:
system("cls"); //清空控制台
Print_Con(&con);
break;
case Sort:
Sqrt_Con(&con);
break;
case Empty:
Empty_Con(&con);
break;
case Exit:
printf("程序退出\n");
SaveContact(&con);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
为了更加清晰,我设置了一个枚举常量,来对case进行标识,具体的枚举常量如下
enum Input
{
Exit, //退出
Add, //增加
Del, //删除
Alt, //更改
Find, //查找
Print, //打印
Sort, //排序
Empty //清空
};
3.初始化通讯录,这里我们要对通讯录先进行初始化
void InitContact(Contact* pc)
{
assert(pc);
pc->Capacity = MAX;
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
LoadContact(pc);
}
这里的LoadContact是为了文件操作,在后面会设计讲设计这个函数(6.文件读取)
4.扩容
因为上面的2.多次运行中我们设置的是动态的内存空间,所以肯定会存在内存不足的情况,所以我们这里就进行一个扩容,一次多增加两个空间,具体代码如下
void Capacity(Contact* pc) //扩容
{
if (pc->sz == pc->Capacity)
{
pc->data = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo) * pc->Capacity + sizeof(PeoInfo) * 2);
pc->Capacity += 2;
if (pc->data == NULL)
{
printf("扩容失败\n");
return;
}
else
printf("扩容成功\n");
}
}
5.文件写入
这里我们可以在exit里面设置一个文件读取,这样我们在退出的时候,可以把我们写在通讯录里面的东西写入到文件里面去
void SaveContact(Contact* pc)
{
//打开文件
FILE* pf = fopen("Contact.txt","wb");
if (pf == NULL)
{
perror("SaveContact::fopen");
return;
}
//写入文件
for (int i = 0; i < pc->sz; i++)
{
fwrite(pc->data+i,sizeof(PeoInfo),1,pf);
}
//关闭文件
fclose(pf);
pf == NULL;
}
6.文件读取
这里我们在每次打开的时候,可以把之前存在文件里面的数据写入到通讯录中,具体代码如下
void LoadContact(Contact* pc)
{
PeoInfo temp;
FILE* pf = fopen("Contact.txt","rb");
if (pf == NULL)
{
perror("LoadContact::fopen");
return;
}
while (fread(&temp, sizeof(PeoInfo), 1, pf))
{
*(pc->data + pc->sz) = temp;
pc->sz++;
Capacity(pc);
}
fclose(pf);
pf == NULL;
}
7.联系人结构体
在这一步我们可以写入联系人到联系人结构体中去,我设计的联系人的结构体如下
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
int age;
}PeoInfo;
typedef struct Contact
{
PeoInfo* data;
int sz;
int Capacity;
}Contact;
这里设计了两个结构体是为了方便记录联系人当前的数据
8.添加联系人
这里我们只需要往联系人结构体里面添加数据就可以了
void ADD(Contact* pc) //添加
{
Capacity(pc);
printf("请输入名字\n");
scanf("%s",pc->data[pc->sz].name);
printf("请输入性别\n");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄\n");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入电话号码\n");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入地址\n");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
fflush(stdin); //清空缓存区
}
9.查找函数
因为查找联系人和删除联系人,修改联系人等都需要进行查找操作,所以我就把查找联系人封装成一个函数
int Find_name(Contact* pc,char c[]) //用名字查找
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, c) == 0)
return i;
}
return -1;
}
10.删除联系人
这里我们只要调用之前的查找联系人函数,然后然后将后面的数据往前面移就可以了
void Del_Con(Contact* pc) //删除
{
char c[MAX_NAME];
if (pc->sz == 0)
{
printf("没有联系人可以删除\n");
return;
}
printf("请输入需要删除的名字\n");
scanf("%s",c);
int ret =Find_name(pc, c);
if (ret == -1)
{
printf("没有找到该数据");
return;
}
for (int i = ret; i < pc->sz-1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
}
11.查找联系人
这里我们只需要调用一下上面的查找函数就可以了
void Find_Con(Contact* pc)
{
char c[MAX_NAME];
printf("请输入需要查找的名字\n");
scanf("%s",c);
int ret = Find_name(pc,c);
if (ret == -1)
{
printf("没有该元素\n");
return;
}
printf("%-20s%-5s%-5s%-13s%-30s\n", "名字", "性别", "年龄", "电话号码", "地址");
printf("%-20s%-5s%-5s%-13s%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].name,
pc->data[ret].tele, pc->data[ret].addr);
}
12.更改联系人信息
这里我们也需要调用查找练习人的信息,然后选择需要更改的项目,最后进行更改就可以了其他的逻辑和上面的多次运行差不多
void Alt_Con(Contact* pc)
{
char c[MAX_NAME];
printf("请输入需要修改的名字\n");
scanf("%s",c);
int ret = Find_name(pc, c);
if (ret == -1)
{
printf("该联系人不存在\n");
return;
}
printf("请选择需要修改的内容\n");
printf("1.名字 2.性别 \n");
printf("3.年龄 4.电话号码 \n");
printf("5.地址 0.放弃修改 \n");
int input;
scanf("%d",&input);
switch (input)
{
case 1 :
printf("请输入需要修改成什么\n");
char nam[MAX_NAME];
scanf("%s",nam);
strcpy(pc->data[ret].name, nam);
break;
case 2 :
printf("请输入需要修改成什么\n");
char sex[MAX_SEX];
scanf("%s", sex);
strcpy(pc->data[ret].sex, sex);
break;
case 3:
printf("请输入需要修改成什么\n");
char age[3];
scanf("%s", age);
strcpy(pc->data[ret].age, age);
break;
case 4:
printf("请输入需要修改成什么\n");
char tele[MAX_TELE];
scanf("%s", tele);
strcpy(pc->data[ret].tele,tele);
break;
case 5:
printf("请输入需要修改成什么\n");
char addr[MAX_ADDR];
scanf("%s", addr);
strcpy(pc->data[ret].addr, addr);
break;
case 0:
return;
break;
default:
printf("输入错误\n");
return;
}
}
13.打印联系人
这里可以把所有练习人的信息打印到屏幕上面,然后清空控制台
void Print_Con(Contact* pc) //打印
{
printf("%-20s%-5s%-5s%-13s%-30s\n","名字","性别","年龄","电话号码","地址");
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s%-5s%-5d%-13s%-30s\n",pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].tele, pc->data[i].addr);
}
}
14.联系人排序
这里我们可以对联系人的名字进行排序,我采用的是比较简单的冒泡排序法
void Sqrt_Con(Contact* pc) //排序
{
int i = 0;
int j = 0;
PeoInfo c;
for (i = 0; i < pc->sz-1; i++)
{
for (j = 0; j < pc->sz-1-i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
c = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = c;
}
}
}
printf("排序完成\n");
}
15.清空联系人
当我们需要重置表的时候,就可以调用清空联系人的函数,这里的代码和初始化很像,但是不可以直接使用初始化函数,因为初始化函数中有读取文件操作
void Empty_Con(Contact* pc) //清空
{
assert(pc);
pc->Capacity = MAX;
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
printf("通讯录已清空\n");
}
16.全部代码
//address.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"address.h"
void InitContact(Contact* pc)
{
assert(pc);
pc->Capacity = MAX;
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
LoadContact(pc);
}
void Capacity(Contact* pc) //扩容
{
if (pc->sz == pc->Capacity)
{
pc->data = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo) * pc->Capacity + sizeof(PeoInfo) * 2);
pc->Capacity += 2;
if (pc->data == NULL)
{
printf("扩容失败\n");
return;
}
else
printf("扩容成功\n");
}
}
void ADD(Contact* pc) //添加
{
Capacity(pc);
printf("请输入名字\n");
scanf("%s",pc->data[pc->sz].name);
printf("请输入性别\n");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄\n");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入电话号码\n");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入地址\n");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
fflush(stdin); //清空缓存区
}
void Print_Con(Contact* pc) //打印
{
printf("%-20s%-5s%-5s%-13s%-30s\n","名字","性别","年龄","电话号码","地址");
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s%-5s%-5d%-13s%-30s\n",pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].tele, pc->data[i].addr);
}
}
//找到返回下标
//没找到返回-1
int Find_name(Contact* pc,char c[]) //用名字查找
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, c) == 0)
return i;
}
return -1;
}
void Del_Con(Contact* pc) //删除
{
char c[MAX_NAME];
if (pc->sz == 0)
{
printf("没有联系人可以删除\n");
return;
}
printf("请输入需要删除的名字\n");
scanf("%s",c);
int ret =Find_name(pc, c);
if (ret == -1)
{
printf("没有找到该数据");
return;
}
for (int i = ret; i < pc->sz-1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
}
void Alt_Con(Contact* pc)
{
char c[MAX_NAME];
printf("请输入需要修改的名字\n");
scanf("%s",c);
int ret = Find_name(pc, c);
if (ret == -1)
{
printf("该联系人不存在\n");
return;
}
printf("请选择需要修改的内容\n");
printf("1.名字 2.性别 \n");
printf("3.年龄 4.电话号码 \n");
printf("5.地址 0.放弃修改 \n");
int input;
scanf("%d",&input);
switch (input)
{
case 1 :
printf("请输入需要修改成什么\n");
char nam[MAX_NAME];
scanf("%s",nam);
strcpy(pc->data[ret].name, nam);
break;
case 2 :
printf("请输入需要修改成什么\n");
char sex[MAX_SEX];
scanf("%s", sex);
strcpy(pc->data[ret].sex, sex);
break;
case 3:
printf("请输入需要修改成什么\n");
char age[3];
scanf("%s", age);
strcpy(pc->data[ret].age, age);
break;
case 4:
printf("请输入需要修改成什么\n");
char tele[MAX_TELE];
scanf("%s", tele);
strcpy(pc->data[ret].tele,tele);
break;
case 5:
printf("请输入需要修改成什么\n");
char addr[MAX_ADDR];
scanf("%s", addr);
strcpy(pc->data[ret].addr, addr);
break;
case 0:
return;
break;
default:
printf("输入错误\n");
return;
}
}
void Find_Con(Contact* pc)
{
char c[MAX_NAME];
printf("请输入需要查找的名字\n");
scanf("%s",c);
int ret = Find_name(pc,c);
if (ret == -1)
{
printf("没有该元素\n");
return;
}
printf("%-20s%-5s%-5s%-13s%-30s\n", "名字", "性别", "年龄", "电话号码", "地址");
printf("%-20s%-5s%-5s%-13s%-30s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].name,
pc->data[ret].tele, pc->data[ret].addr);
}
void Sqrt_Con(Contact* pc) //排序
{
int i = 0;
int j = 0;
PeoInfo c;
for (i = 0; i < pc->sz-1; i++)
{
for (j = 0; j < pc->sz-1-i; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
c = pc->data[j];
pc->data[j] = pc->data[j + 1];
pc->data[j + 1] = c;
}
}
}
printf("排序完成\n");
}
void Empty_Con(Contact* pc) //清空
{
assert(pc);
pc->Capacity = MAX;
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
printf("通讯录已清空\n");
}
void SaveContact(Contact* pc)
{
//打开文件
FILE* pf = fopen("Contact.txt","wb");
if (pf == NULL)
{
perror("SaveContact::fopen");
return;
}
//写入文件
for (int i = 0; i < pc->sz; i++)
{
fwrite(pc->data+i,sizeof(PeoInfo),1,pf);
}
//关闭文件
fclose(pf);
pf == NULL;
}
void LoadContact(Contact* pc)
{
PeoInfo temp;
FILE* pf = fopen("Contact.txt","rb");
if (pf == NULL)
{
perror("LoadContact::fopen");
return;
}
while (fread(&temp, sizeof(PeoInfo), 1, pf))
{
*(pc->data + pc->sz) = temp;
pc->sz++;
Capacity(pc);
}
fclose(pf);
pf == NULL;
}
//address.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 3
#define MAX_TELE 12
#define MAX_ADDR 30
#define MAX 1
enum Input
{
Exit, //退出
Add, //增加
Del, //删除
Alt, //更改
Find, //查找
Print, //打印
Sort, //排序
Empty //清空
};
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
int age;
}PeoInfo;
typedef struct Contact
{
PeoInfo* data;
int sz;
int Capacity;
}Contact;
void InitContact(Contact* pc); //非文件的初始化
void ADD(Contact* pc); //添加联系人
void Print_Con(Contact* pc); //打印联系人
void Del_Con(Contact* pc); //删除联系人
void Alt_Con(Contact* pc); //修改联系人
void Find_Con(Contact* pc); //查找联系人
void Sqrt_Con(Contact* pc); //排序联系人
void Empty_Con(Contact* pc); //清空联系人
void Capacity(Contact* pc); //扩容
void SaveContact(Contact* pc); //将联系人以二进制写入文件
void LoadContact(Contact* pc); //以二进制文件的方式初始化联系人
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"address.h"
#include<stdio.h>
void menu()
{
printf("**************************************\n");
printf("*****1.Add 2.Del***********\n");
printf("*****3.Alt 4.Find**********\n");
printf("*****5.Print 6.Sort**********\n");
printf("*****7.Empty 0.Exit**********\n");
printf("**************************************\n");
}
int main()
{
int input;
Contact con = {0};
con.data = (PeoInfo*)malloc(sizeof(PeoInfo) * MAX);
if (con.data == NULL)
{
printf("开辟空间失败\n");
return -1;
}
InitContact(&con);
do
{
menu();
printf("请选择:>\n");
scanf("%d", &input);
switch (input)
{
case Add:
ADD(&con);
break;
case Del:
Del_Con(&con);
break;
case Alt:
Alt_Con(&con);
break;
case Find:
Find_Con(&con);
break;
case Print:
system("cls"); //清空控制台
Print_Con(&con);
break;
case Sort:
Sqrt_Con(&con);
break;
case Empty:
Empty_Con(&con);
break;
case Exit:
printf("程序退出\n");
SaveContact(&con);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
快去创建自己的通讯录吧