这是到目前为止写过的最复杂的东西……三百多行啊……虽然是跟着视频一句句敲出来的,但毕竟是自己敲的……想想还有点小激动呢……
// 引入头文件
#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];
// 定义联系人个数
int totalContactCount = 0;
// 定义变量接收用户输入的功能编号
int fno;
// 定义数据文件保存位置
char *filePath = "telbook.data";
// ****************** 函数声明部分 *******************
int validateInput(int num, int min, int max);
void doAdd();
void doDelete();
void doUpdate();
void doList();
void doSearchByname();
void init();
void fileWrite();
int main(int argc, const char * argv[]) {
/*
1.引入头文件
2.进行必要的宏定义
3.定义文件名称变量、联系人数组、联系人结构体
4.定义函数,并进行函数声明
5.编写循环控制程序
6.显示操作界面
7.根据编号执行不同的函数
*/
// 初始化通讯录
init();
printf("通讯录初始化完成。");
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");
// 提示用户选择一个序号
printf("请输入1~6选择相应功能:\n");
// 接收用户输入的编号
scanf("%d", &fno);
// 根据用户输入的编号执行不同操作
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:
// 提示输入不合法
printf("输入不合法!");
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;
}
/**
* 添加联系人
*/
void doAdd(){
printf("您选择的是添加联系人,请按提示操作:\n");
// 提示用户输入联系人姓名
printf("请输入联系人姓名:(*注意联系人姓名中间不能有空格)\n");
// 接收联系人姓名
scanf("%s", contacts[totalContactCount].name);
// 提示用户输入联系人电话号码
printf("请输入联系人电话号码(*注意电话号码之间不能有空格)\n");
// 接收电话号码
scanf("%s", contacts[totalContactCount].telNum);
// 确认添加
printf("您确认要添加数据吗?1.确认 0.取消\n");
int flag;
scanf("%d",&flag);
if (flag) {
// 联系人的个数+1
totalContactCount ++;
// 把联系人信息写入文件
fileWrite();
}
}
/**
* 删除联系人
*/
void doDelete(){
printf("您选择的是删除联系人,请按提示操作:\n");
// 先把所有联系人打印出来
doList();
// 提示用户输入一个编号
printf("请输入要删除的联系人的编号:\n");
int no;
scanf("%d", &no);
// 判断输入是否合法
if(validateInput(no, 1, totalContactCount)){
return;
}
// 提示用户是否确认删除
int flag;
printf("删除后联系人数据不可恢复,是否确认删除:1.确认 0.返回 \n");
scanf("%d",&flag);
// 开始删除数组元素
// 删除的正好是数组的最后一个元素
if (no == totalContactCount) {
// 只要让联系人数量-1
totalContactCount --;
printf("数据更新成功。\n");
} else{
// 如果删除的元素不是数组的最后一个元素
// 需要移动数组元素
for (int i = no; i < totalContactCount; i ++) {
contacts[i - 1] = contacts[i];
}
// 联系人数量-1
totalContactCount --;
// 同步更新到文件中
fileWrite();
}
}
/**
* 修改联系人
*/
void doUpdate(){
printf("您选择的是修改联系人,请按提示操作:\n");
// 先把所有联系人打印出来
doList();
// 提示用户输入要修改的联系人编号
int no;
printf("请输入要修改的联系人编号:\n");
scanf("%d", &no);
// 判断输入是否合法
if(validateInput(no, 1, totalContactCount)){
return;
}
// 输入新的联系人姓名和电话
char newName[NAMELEN];
char newTel[NUMLEN];
printf("请输入新的联系人姓名(*姓名之间不能有空格):\n");
scanf("%s",newName);
printf("请输入新的联系人电话号码(*电话号码间不能有空格):\n");
scanf("%s",newTel);
// 让用户确认修改
int flag;
printf("是否确定修改?1.确定 0.返回\n");
scanf("%d",&flag);
if (flag) {
// 更新数组信息
strcpy(contacts[no-1].name, newName);
strcpy(contacts[no-1].telNum, newTel);
// 写入到文件中
fileWrite();
}
}
/**
* 显示所有联系人
*/
void doList(){
printf("所有联系人数据如下:\n");
// 判断通讯录是否为空
if (totalContactCount == 0) {
printf("您的通讯录还没有小伙伴,请添加……\n");
} else{
// 输出格式
printf("编号\t 姓名\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);
}
}
}
/**
* 搜索联系人
*/
void doSearchByname(){
printf("您选择的是搜索联系人,请按提示操作:\n");
// 提示用户输入要搜索的联系人姓名
printf("请输入要查找的联系人姓名:\n");
char searchName[NAMELEN];
scanf("%s", searchName);
// 按照姓名进行查找
int i;
for (i = 0; i < totalContactCount; i ++) {
if (strcmp(contacts[i].name, searchName) == 0) { // 如果下标为i的联系人姓名等于用户要查找的姓名
// 打印出姓名和电话号码
printf("姓名:%s, 电话:%s\n", contacts[i].name, contacts[i].telNum);
break; // 结束循环
}
}
// 如果遍历结束还没找到
if (i == totalContactCount) {
// 说明文件里没有这个联系人
printf("对不起,查无此人。\n");
}
}
/**
通讯录的初始化工作
1.尝试读取数据文件
2.如果读取成功,说明文件存在
如果文件存在,读取联系人数据,保存到联系人数组contacts中
3.如果读取失败,说明是第一次使用通讯录
如果第一次使用
1)创建联系人数据文件
2)把当前联系人的个数写入文件 totalContactCount = 0
*/
void init(){
// 定义文件指针,并打开文件
FILE *fp = fopen(filePath, "r");
if (fp != NULL) {
// 第一步:读取联系人个数
fread(&totalContactCount, sizeof(totalContactCount), 1, fp);
// 第二步:读取每个联系人
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);
}
/**
* 写入联系人信息
*/
void fileWrite(){
// 定义文件指针,并打开文件
FILE *fp = fopen(filePath, "wb");
if (fp != NULL) {
// 写入联系人个数
fwrite(&totalContactCount, sizeof(totalContactCount), 1, fp);
// 写入联系人信息
for (int i =0; i < totalContactCount; i ++) {
fwrite(&contacts[i], sizeof(Person), 1, fp);
}
printf("文件数据更新成功!\n");
}
// 关闭指针
fclose(fp);
}