实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
静态内存开辟点击打开链接
上一篇博客写出了先给结构体开辟一块大小固定的空间,然后往里面存放数据,但是这种方法会造成很大的内存浪费,如果存两个数据那么就有998块内存浪费,还是很吃内存的,所以用动态内存开辟的方法可以很好的解决这个问题,不够了再给你加,管饱!
下面是代码实现:
Contact.h
#ifndef __CONTACT_H__
#define __CONTACT_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#define NAME_MAX 20
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 30
#define MAX 1000
#define M 2
#define N 5
typedef struct PeoInfo //定义一个存一个数据的结构体
{
char name[NAME_MAX];
char sex[SEX_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact //定义一个能存放1000个类型为PeoInfo类型的结构体
{
PeoInfo *data;
int sz; //已用空间
int count; //总用空间
};
typedef struct Contact *Contact; //将结构体重命名为一个结构体指针,用来直接指向结构体内容
void InitContact(Contact pcon);
int add_con(Contact pcon);
int del_con(Contact pcon);
int find_con(Contact pcon);
int modifty_con(Contact pcon);
int show_con(Contact pcon);
int empty_con(Contact pcon);
int sort_con(Contact pcon);
void send_out(Contact pcon);
#endif //__CONTACT_H__
Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void InitContact(Contact pcon) //静态初始化
{
pcon->data = (PeoInfo *)malloc(M*sizeof(PeoInfo)); //先给PeoInfo结构分配M大小的内存
if(pcon->data == NULL) //如果存放数据的空间不够了,则输出没空间了
{
printf("out of memory\n");
exit(1);
}
else
{
memset(pcon->data,0,M*sizeof(PeoInfo));
pcon->sz = 0; //已存数据为0
pcon->count = M; //将通讯录总数据初始化为M
}
}
void check_memory(Contact pcon) //检查内存是否够用
{
if(pcon->sz == pcon->count) //如果已用内存和总内存相同,则内存不够用了
{
PeoInfo *str = (PeoInfo *)realloc(pcon->data,(pcon->count+N)*sizeof(PeoInfo)); //将data的内存增加N个
if(str == NULL)
{
printf("out of memory\n");
exit(1);
}
else
{
pcon->data = str; //将新分配到的内存给data,同时data的内容也拷贝过来
pcon->count += N; //将总大小每次增加N个,不够再分,能节省内存
}
}
}
int add_con(Contact pcon) //添加数据
{
check_memory(pcon);
printf("请输入姓名:>");
scanf("%s",pcon->data[pcon->sz].name);
printf("请输入性别:>");
scanf("%s",pcon->data[pcon->sz].sex);
printf("请输入年龄:>");
scanf("%d",&pcon->data[pcon->sz].age);
printf("请输入电话号码:>");
scanf("%s",pcon->data[pcon->sz].tel);
printf("请输入地址:>");
scanf("%s",pcon->data[pcon->sz].addr);
printf("添加成功\n");
pcon->sz++; //存一个计数器加1
return 0;
}
int del_con(Contact pcon) //要删除的数据
{
int i = 0;
int ret = 0;
int tmp = 0;
if(pcon->sz == 0) //如果没有数据则返回-1
{
printf("通讯录里没有信息\n");
return 0;
}
ret = find_con(pcon); //先遍历一遍
printf("确定删除吗? 1、确定 0、取消\n");
scanf("%d",&tmp);
if(tmp == 0)
return 0;
if(ret != -1)
{
for(i=ret; i<(pcon->sz)-1; i++);
{
pcon->data[ret] = pcon->data[ret+i]; //删除相当于把后面的数据依次向前覆盖前面的数据
}
pcon->sz--; //删除之后计数器减1
return 1;
}
else
{
printf("没有要删除的人\n");
return -1;
}
}
int find_con(Contact pcon) //查找,为后面的其他选项提供遍历
{
int i = 0;
char name[NAME_MAX];
printf("请输入名字:>");
scanf("%s",name);
printf("%10s%6s%6s%14s%20s\n","姓名","性别","年龄","电话","地址");
for(i=0; i<pcon->sz; i++)
{
if(strcmp(pcon->data[i].name,name)==0)
{
printf("%10s",pcon->data[i].name);
printf("%6s",pcon->data[i].sex);
printf("%6d",pcon->data[i].age);
printf("%14s",pcon->data[i].tel);
printf("%20s",pcon->data[i].addr);
printf("\n");
return i;
}
}
return -1;
}
int modifty_con(Contact pcon) //要修改的内容
{
int i = 0;
int ret = 0;
if(pcon->sz == 0) //如果没数据则返回
{
printf("没有可修改的数据\n");
return 0;
}
ret = find_con(pcon); //先在遍历一遍,看有没有要修改的数据
if(ret != -1)
{
printf("请重新输入要改的数据\n");
printf("请输入姓名:>");
scanf("%s",pcon->data[ret].name);
printf("请输入性别:>");
scanf("%s",pcon->data[ret].sex);
printf("请输入年龄:>");
scanf("%d",&pcon->data[ret].age);
printf("请输入电话:>");
scanf("%s",pcon->data[ret].tel);
printf("请输入地址:>");
scanf("%s",pcon->data[ret].addr);
printf("修改成功\n");
return 1;
}
else
{
printf("没找到要修改的名字\n");
return -1;
}
}
int show_con(Contact pcon) //将所有信息按存入时间来显示出来
{
int i = 0;
printf("%10s%6s%6s%14s%20s\n","姓名","性别","年龄","电话","地址");
for(i=0; i<pcon->sz; i++) //时间顺序
{
printf("%10s",pcon->data[i].name);
printf("%6s",pcon->data[i].sex);
printf("%6d",pcon->data[i].age);
printf("%14s",pcon->data[i].tel);
printf("%20s",pcon->data[i].addr);
printf("\n");
}
printf("\n");
return 0;
}
int empty_con(Contact pcon) //清空数据
{
pcon->sz = 0; //只是将要计数器清零,实际数据还在(相当于地址变为起始地址指针)
return 0;
}
int sort_con(Contact pcon) //按姓名字母大小排序显示
{
int tmp = 0;
int ret = 0;
int i = 0;
int j = 0;
PeoInfo swp ; //定义另一个PeoInfo的对象
if(pcon->sz == 0) //如果列表为空,则返回
{
printf("没有可靠的数据\n");
return 0;
}
for(i=0; i<pcon->sz-1; i++)
{
for(j=0; j<pcon->sz-i-1; j++)
{
if(strcmp(pcon->data[j].name,pcon->data[j+1].name)>0) //按照名字的大小,按照从小到大冒泡排序
{
swp = pcon->data[j];
pcon->data[j] = pcon->data[j+1];
pcon->data[j+1] = swp;
}
}
}
tmp = show_con(pcon); //将排序后的打印出来
return 0;
}
void send_out(Contact pcon)
{
if(pcon->data != NULL)
free(pcon->data);
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void menu()
{
printf("***************************************************\n");
printf("***1、添加联系人信息 2、删除指定联系人信息***\n");
printf("***3、查找指定联系人信息 4、修改指定联系人信息***\n");
printf("***5、显示所有联系人信息 6、清空所有联系人 ***\n");
printf("***7、以名字排序所有联系人 0、exit ***\n");
printf("***************************************************\n");
}
enum OP //用枚举法列出选项,直观
{
EXIT,
ADD,
DEL,
FIND,
MOD,
SHOW,
EMPTY,
SORT
};
void test()
{
int input = 0;
struct Contact my_con; //创建一个struct Contact类型的对象
my_con.sz = 0; //将计数器清零
InitContact(&my_con); //初始化对象
do
{
menu();
printf("请输入你的选择:>");
scanf("%d",&input);
switch (input)
{
case ADD:
add_con(&my_con);
break;
case DEL:
del_con(&my_con);
break;
case FIND:
find_con(&my_con);
break;
case MOD:
modifty_con(&my_con);
break;
case SHOW:
show_con(&my_con);
break;
case EMPTY:
empty_con(&my_con);
break;
case SORT:
sort_con(&my_con);
break;
case EXIT:
printf("退出\n");
break;
default:
printf("选择错误\n");
break;
}
}while(input);
}
int main()
{
test();
system("pause");
return 0;
}