// 通讯录应用
#include <stdio.h>
#include <string.h>
//进行宏定义
#define N 100
//定义通讯录的容量
#define NAMELEN 22
#define NUMLEN 12
//************定义部分*********
//定义联系人的结构体
typedef
struct
{
//联系人
char
name
[
NAMELEN
];
//电话号码
char
telNum
[
NUMLEN
];
}
Person
;
//存储所有的联系人,联系人的数组
Person
contacts
[
N
];
//能够存储100个联系人
//定义联系人的个数
int
totalContactCount
=
0
;
//接收用户输入的编号
int
fno
;
//定义数据文件保存的位置
char
*
filePath
=
"telbook.data"
;
//************* 函数的声明部分 *********
int
validateInput
(
int
num
,
int
min
,
int
max
);
void
init
();
void
doAdd
();
void
doDelete
();
void
doUpdate
();
void
doList
();
void
doSearchByName
();
void
writeFile
();
int
main
(
int
argc
,
const
char
*
argv
[])
{
/**
1、引入头文件
2、进行必要的宏定义
3、定义文件名称变量、联系人数组、联系人结构体
4、定义函数,并进行函数声明
5、编写循环控制程序
6、显示操作界面
7、根据编号执行不同的函数
*/
init
();
printf
(
"通讯录初始化完成!
\n
"
);
while
(
1
)
{
printf
(
"
\n
"
);
//软件的界面显示出来
printf
(
"**************************
\n
"
);
printf
(
"****** 欢迎使用通讯录 ******
\n
"
);
printf
(
"****** 1、添加联系人 ******
\n
"
);
printf
(
"****** 2、删除联系人 ******
\n
"
);
printf
(
"****** 3、修改联系人 ******
\n
"
);
printf
(
"****** 4、查看所有联系人 ****
\n
"
);
printf
(
"****** 5、搜索联系人 ******
\n
"
);
printf
(
"****** 6、退出系统 ******
\n
"
);
printf
(
"**************************
\n\n
"
);
//提示用户选择一个序号
printf
(
"请选择1-6之间的功能编号:
\n
"
);
scanf
(
"%d"
,
&
fno
);
//判断编号是否合法
validateInput
(
fno
,
1
,
6
);
switch
(
fno
)
{
case
1:
//执行添加
doAdd
();
break
;
case
2:
//执行删除
doDelete
();
break
;
case
3:
//执行修改
doUpdate
();
break
;
case
4:
//执行显示所有联系人
doList
();
break
;
case
5:
//执行查找
doSearchByName
();
break
;
case
6:
//执行退出系统
printf
(
"系统正在退出...
\n
"
);
printf
(
"系统已经退出!
\n
"
);
return
0
;
break
;
default:
break
;
}
}
return
0
;
}
/**
* 验证输入是否合法
*
* @param num 待验证的数
* @param min 最小值
* @param max 最大值
*
* @return 1 非法, 0 正常
*/
int
validateInput
(
int
num
,
int
min
,
int
max
){
if
(
num
<
min
||
num
>
max
)
{
printf
(
"非法的输入!"
);
return
1
;
}
return
0
;
}
/**
* 添加联系人
思路:
1、提示用户输入联系人姓名
2、接收联系人
3、提示用户输入电话号码
4、接收电话号码
5、确认添加
6、联系人的个数+1
7、把联系人信息写入到文件中
*/
void
doAdd
(){
printf
(
"您选择的是添加联系人,请按提示操作:
\n
"
);
//1、提示用户输入联系人姓名
printf
(
"请输入联系人姓名:(*注意联系人姓名中间不能有空格)
\n
"
);
//totalContactCount = 0
//4 0 - 3
//2、接收联系人
scanf
(
"%s"
,
contacts
[
totalContactCount
].
name
);
//3、提示用户输入电话号码
printf
(
"请输入联系人电话:(*注意联系人电话号码中间不能有空格)
\n
"
);
//4、接收电话号码
scanf
(
"%s"
,
contacts
[
totalContactCount
].
telNum
);
//5、确认添加
int
flag
;
printf
(
"您确认要添加数据吗?1.确认 0.取消
\n
"
);
scanf
(
"%d"
,
&
flag
);
if
(
flag
)
{
//6、联系人的个数+1
totalContactCount
++
;
//7、把联系人信息写入到文件中
writeFile
();
}
}
/**
* 删除联系人
思路:
1、提示用户输入一个联系人编号
2、判断编号是否合法 编号不能大于联系人个数
3、提示用户再次确认删除
4、开始删除数组元素
1)删除的元素正好是数组的最后一个元素
只需要让联系人个数-1
2)如果删除的元素不是数组的最后一个元素
需要移动元素
联系人数量-1
5、同步更新到文件中
*/
void
doDelete
(){
printf
(
"您选择的是删除联系人,请按提示操作:
\n
"
);
doList
();
//1、提示用户输入一个联系人编号
int
no
;
printf
(
"请输入要删除的联系人的编号:
\n
"
);
scanf
(
"%d"
,
&
no
);
//2、判断编号是否合法 编号不能大于联系人个数
if
(
validateInput
(
no
,
1
,
totalContactCount
))
{
return
;
}
//3、提示用户再次确认删除
int
flag
;
printf
(
"删除联系人后,数据将无法恢复,您缺人要删除吗?1.确认 0.取消
\n
"
);
scanf
(
"%d"
,
&
flag
);
if
(
flag
)
{
//4、开始删除数组元素
// 1)删除的元素正好是数组的最后一个元素
if
(
no
==
totalContactCount
)
{
totalContactCount
--
;
}
else
{
// 只需要让联系人个数-1
// 2)如果删除的元素不是数组的最后一个元素
// 需要移动元素
for
(
int
i
=
no
;
i
<
totalContactCount
;
i
++
)
{
//元素的移动和覆盖
contacts
[
no
-
1
]
=
contacts
[
no
];
}
// 联系人数量-1
totalContactCount
--
;
}
//5、同步更新到文件中
writeFile
();
}
}
/**
* 修改联系人
思路:
1、提示用户输入修改的信息编号
2、验证编号是否合法
3、输入新的用户名和新的电话号码
4、让用户再次确认修改
5、更新数组信息
6、写入到文件中
*/
void
doUpdate
(){
printf
(
"您选择的是修改联系人,请按提示操作:
\n
"
);
doList
();
//列表所有的联系人
// 1、提示用户输入修改的信息编号
int
no
;
printf
(
"请输入要修改的联系人的编号:
\n
"
);
scanf
(
"%d"
,
&
no
);
//2、判断编号是否合法 编号不能大于联系人个数
if
(
validateInput
(
no
,
1
,
totalContactCount
))
{
return
;
}
// 3、输入新的用户名和新的电话号码
char
name1
[
NAMELEN
];
char
tel
[
NUMLEN
];
printf
(
"请输入联系人新的姓名:(*注意联系人姓名中间不能有空格)
\n
"
);
scanf
(
"%s"
,
name1
);
printf
(
"请输入联系人新的电话:(*注意联系人电话中间不能有空格)
\n
"
);
scanf
(
"%s"
,
tel
);
// 4、让用户再次确认修改
int
flag
;
printf
(
"确认后,信息将永久修改,您确认修改吗?1.确认 0.取消
\n
"
);
scanf
(
"%d"
,
&
flag
);
if
(
flag
)
{
// 5、更新数组信息
strcpy
(
contacts
[
no
-
1
].
name
,
name1
);
strcpy
(
contacts
[
no
-
1
].
telNum
,
tel
);
//contacts[n-1].name = "xxxx";
// 6、写入到文件中
writeFile
();
}
}
/**
* 显示所有联系人
思路:
前提:系统已经完成了初始化工作(如果文件存在则读取文件中的所有的数据)
1、首先做一个判断
totalContactCount == 0 //表示没有联系人
2、如果不等于0
开始遍历,并且输出联系人的信息
*/
void
doList
(){
printf
(
"显示所有联系人,联系人数据如下:
\n
"
);
//判断通讯录是否为空
if
(
totalContactCount
==
0
){
printf
(
"您的通讯录还没有小伙伴~请添加小伙伴!
\n
"
);
}
else
{
//输出格式
printf
(
"编号
\t
姓名
\t
电话
\t
\n
"
);
//遍历联系人数组
for
(
int
i
=
0
;
i
<
totalContactCount
;
i
++
){
printf
(
"%d
\t
%s
\t
%s
\t
\n
"
,
i
+
1
,
contacts
[
i
].
name
,
contacts
[
i
].
telNum
);
}
}
}
/**
* 搜索联系人
思路;
1、提示用户输入要搜索的联系人姓名
2、按照姓名进行查找(遍历)
1)输入的姓名和contacts[i].name 比较
2)搜索不到
遍历一遍 都没有这个名称 提示查找不到
*/
void
doSearchByName
(){
printf
(
"您选择的是搜索联系人,请按提示操作:
\n
"
);
// 1、提示用户输入要搜索的联系人姓名
char
name
[
NAMELEN
];
printf
(
"请输入要查找的联系人:
\n
"
);
scanf
(
"%s"
,
name
);
// 2、按照姓名进行查找(遍历)
int
i
;
for
(
i
=
0
;
i
<
totalContactCount
;
i
++
)
{
//1)输入的姓名和contacts[i].name 比较
//比较两个字符串是否相等 strcmp() == 0
if
(
strcmp
(
name
,
contacts
[
i
].
name
)
==
0
)
{
//打印出来姓名对应的电话号码
printf
(
"您搜索的联系人 %s 的电话号码是:%s
\n
"
,
name
,
contacts
[
i
].
telNum
);
break
;
//循环要停止
}
}
//
//
// 2)搜索不到
// 遍历一遍 都没有这个名称 提示查找不到
if
(
i
==
totalContactCount
)
{
printf
(
"对不起,查无此人!
\n
"
);
}
}
/**
通讯录的初始化工作
1、尝试读取数据文件
2、如果读取成功,说明文件存在
如果存在,要读取联系人数据,保存到联系人数组 contacts
3、如果读取失败,说明我们是第一次使用通讯录
如果是第一次使用
1)创建联系人数据文件
2)把当前联系人的个数写入到文件中 totalContactCount = 0
*/
void
init
(){
//定义文件指针,并且打开文件
FILE
*
fp
=
fopen
(
filePath
,
"r"
);
if
(
fp
!=
NULL
){
//第一步:读取联系人的个数 4
fread
(
&
totalContactCount
,
sizeof
(
totalContactCount
),
1
,
fp
);
//第二步:读取每一个联系人 34
for
(
int
i
=
0
;
i
<
totalContactCount
;
i
++
)
{
//读取联系人数据到联系人数组中
fread
(
&
contacts
[
i
],
sizeof
(
Person
),
1
,
fp
);
}
}
else
{
//创建文件
fp
=
fopen
(
filePath
,
"wb"
);
//写入联系人的个数
fwrite
(
&
totalContactCount
,
sizeof
(
totalContactCount
),
1
,
fp
);
printf
(
"通讯录文件创建成功~!
\n
"
);
}
//关闭文件指针
fclose
(
fp
);
}
/**
* 写数据到文件中
思路:
1、以wb方式打开文件
2、先写联系人个数
3、写每个联系人数据
*/
void
writeFile
(){
//1、以wb方式打开文件
FILE
*
fp
=
fopen
(
filePath
,
"wb"
);
if
(
fp
!=
NULL
)
{
//2、先写联系人个数
fwrite
(
&
totalContactCount
,
sizeof
(
totalContactCount
),
1
,
fp
);
//3、写每个联系人数据
for
(
int
i
=
0
;
i
<
totalContactCount
;
i
++
){
//每次都写入一个数组的元素
fwrite
(
&
contacts
[
i
],
sizeof
(
Person
),
1
,
fp
);
}
printf
(
"写文件数据更新成功!
\n
"
);
}
//4、关闭文件指针
fclose
(
fp
);
}