实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
通讯录可以用来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
一,要想实现一个通讯录,不要着急着写,思考清楚后,很easy
第一步:把可能用到的函数声明,枚举类型,库函数都写到头文件里(没想到的话,先不用写)
我的头文件如下:
#ifndef _ADDR_H_ //防止头文件被重复引用
#define _ADDR_H_
enum
{
EXIT, //枚举的优点是增加代码的可读性,有类型检查,更严谨,便于调试,防止命名污染,定义多个变量
ADD,
SEARCH,
DELETE,
MOD,
SHOW,
SORT,
EMPTY,
};
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 1000
typedef struct peoinfo
{
char name[10];
short age;
char sex[5];
char addr[10];
}peoinfo;
typedef struct record
{
peoinfo elem[MAX_SIZE];
int sz ;
}record;
void add(record *p);
void search(record *p);
void show(record *p);
void empty(record *p);
void sort(record *p);
void mod(record *p);
void del(record *p);
#endif
第二步:
先写测试文件,主要是实现函数封装,便于调用
#include"addr.h"
void menu()
{
printf("***********************************\n");
printf("****0.exit 1.add 2.search***\n");
printf("****3.delete 4.mod 5.show ***\n");
printf("****6.sort 7.empty ***\n");
printf("***********************************\n");
}
int main()
{
int input = 0;
int count = 0;
record p; 创建一个结构体p
p.sz = 0;
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch(input)
{
case ADD:
add(&p);
break;
case SEARCH:
search(&p);
break;
case DELETE:
del(&p);
break;
case MOD:
mod(&p);
break;
case SHOW:
show(&p);
break;
case SORT:
sort(&p);
break;
case EMPTY:
empty(&p);
break;
}
}
while(input);
return 0;
}
第三步:
具体写函数内部功能,如果不需要别人看到的函数,只有自己来使用的话,用static修饰,使函数具有内部链接属性,更加安全
#include"addr.h"
void add(record *p)
{
assert(p!=NULL);
printf("输入姓名:>");
scanf("%s",&p->elem[p->sz].name);
printf("输入年龄:>");
scanf("%d",&p->elem[p->sz].age);
printf("输入性别:>");
scanf("%s",&p->elem[p->sz].sex);
printf("输入地址:>");
scanf("%s",&p->elem[p->sz].addr);
p->sz++;
printf("增加成功");
}
static int sea(record *p) //具有内部链接属性
{
int i = 0;
char name[10] = {'\0'};
assert(p!=NULL);
printf("输入姓名:>");
scanf("%s",&name);
for(i=0; i<p->sz; i++)
{
if(strcmp(name,(p->elem[i].name))==0)
return i;
}
return -1;
}
void search(record *p)
{
int i = 0;
i = sea(p);
assert(p!=NULL);
if(i != -1)
{
printf("找到了\n");
printf("姓名:%s,年龄:%d,性别:%s,地址:%s\n",
p->elem[i].name,
p->elem[i].age,
p->elem[i].sex,
p->elem[i].addr);
}
else
printf("没有找到\n");
}
void show(record *p)
{
int j = 0;
assert(p!=NULL);
printf("姓名 年龄 性别 地址\n");
for(j=0; j<p->sz; j++)
{
printf("%-6s %-6d %-6s %-6s\n",
p->elem[j].name,
p->elem[j].age,
p->elem[j].sex,
p->elem[j].addr);
}
}
void empty(record *p)
{
assert(p!=NULL);
p->sz = 0;
}
void del(record *p)
{
int ret = 0;
assert(p!=NULL);
ret = sea(p);
if(ret != -1||ret<=p->sz)
{
int i = 0;
for(i=ret; i<p->sz-1; i++) //删除操作,把后面的内容往前移动
{
p->elem[i]=p->elem[i+1];
}
p->sz--;
}
else
printf("没有找到联系人");
}
void sort(record *p) //用冒泡排序法
{
int i = 0;
int j = 0;
int flag = 0;
assert(p!=NULL);
if(p->sz == 0)
return ;
for(i=0; i<p->sz-1; i++)
{
for(j=0; j<p->sz-1-i; j++)
{
if(strcmp(p->elem[i].name ,p->elem[i+1].name)>0)
{
peoinfo tmp = p->elem[i]; //交换
p->elem[i]=p->elem[i+1];
p->elem[i+1] = tmp;
flag = 1;
}
}
if(flag == 0) //只用名字排序,所以不需要比较其他的
break;
}
printf("排序成功\n");
}
void mod(record *p) //修改函数
{
int ret = 0;
assert(p!=NULL);
ret = sea(p);
if(ret!=-1)
{
printf("输入要修改的姓名:");
scanf("%s",&p->elem[ret].name );
printf("输入要修改的年龄:");
scanf("%d",&p->elem[ret].age );
printf("输入要修改的性别:");
scanf("%s",&p->elem[ret].sex );
printf("输入要修改的地址:");
scanf("%s",&p->elem[ret].addr );
printf("修改成功");
}
else
printf("没有找到联系人");
}
是不是很简单呢?如果你还想知道动态通讯录,可以看我的下篇博客