也没什么需要说明的,注释完整,本想再集成一个本地联系人文件加密的,胳膊疼,就不多写了。
环境:Ubuntu18.04下GCC通过编译,就是需要修改一下首页显示格式
CLion编译执行完美
windows下使用的话,需要更改一下路径转义字符
共计750多行,耐心点......
底部附带两张运行界面图,需要图形界面的话用这套个壳就行了
/******************************************************************
* Project Name: 通讯录
* By:JP_Shame
* TIME:20190815---20190816
******************************************************************
* Function:
* 1.mianPage();
* 2.void selectFunction();
* 3.void loadContactFile();
* 4.void findContact();
* 5.void creatContact();
* 6.void deleteContact();
* 7.void updateContact();
* 8.void destroyContact();
* 9.void findAllContact();
* 10.int scanContactFile();
* 11.int getContactLines();
* 12.int main(void);
* 13.void freeSpace();
*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//联系人信息结构体
typedef struct contact {
char *name;
char *number;
char *addr;
} Contact;
//两个全局变量,后期使用
Contact *person = NULL;
Contact *allPerson = NULL;
//首页
void mainPage() {
printf("*********************************\n");
printf("*\t\t\t 联系人管理\t\t\t*\n");
printf("*\t\t\t\t\t\t\t\t*\n");
printf("*\t\t\t1.查找联系人\t\t\t*\n");
printf("*\t\t\t2.新增联系人\t\t\t*\n");
printf("*\t\t\t3.删除联系人\t\t\t*\n");
printf("*\t\t\t4.修改联系人\t\t\t*\n");
printf("*\t\t\t5.清空联系人\t\t\t*\n");
printf("*\t\t\t6.所有联系人\t\t\t*\n");
printf("*\t\t\t0.退出该程序\t\t\t*\n");
printf("*********************************\n");
}
//获取联系人个数,本可以直接调用形参避免再次增加文件进程,为了后期使用便利重新打开
int getContactLines() {
FILE *file = fopen("./Contact.txt", "r");
if (!file) {
printf("获取通讯录个数时载入失败\n");
return -1;
}
//临时辅助指针
char *temp = (char *) malloc(sizeof(char) * 1024);
if (!temp)
return -1;
//个数累计变量
int line = 0;
//挨行读取
while (fgets(temp, 1024, file)) {
line++;
//临时指针空间清零
memset(temp, 0, 1024);
}
//释放临时指针
free(temp);
temp = NULL;
fclose(file);
return line;
}
//加载联系人文件到堆区
void loadContactFile() {
//获取联系人个数,开辟对应大小堆空间
int line = getContactLines();
//查找联系人
FILE *file = fopen("./Contact.txt", "r");
if (!file) {
printf("查找联系人时通讯录载入失败\n");
return;
}
allPerson = malloc(sizeof(Contact) * line);
if (!allPerson)
return;
//信息临时储存地
char *information = (char *) malloc(sizeof(char) * 1024);
if (!information) {
return;
}
//临时承载器皿,用数组便于度量字符串长度
char tname[31] = {0};
char tnum[20] = {0};
char taddr[61] = {0};
//作为二级指针数组下标使用
int i = 0;
//开始读取
while (fgets(information, 1024, file)) {
//printf("%s\n", information);
//格式化放入临时空间
sscanf(information, "%[^#]#%[^#]#%s", tname, tnum, taddr);
//printf("%ld\n", strlen(tname) + 1);
//动态开辟结构体内部成员空间,不会造成空间浪费
allPerson[i].name = (char *) malloc(sizeof(char) * strlen(tname) + 1);
allPerson[i].number = (char *) malloc(sizeof(char) * strlen(tnum) + 1);
allPerson[i].addr = (char *) malloc(sizeof(char) * strlen(taddr) + 1);
//将数组中临时信息拷贝到指定堆区中
strcpy(allPerson[i].name, tname);
strcpy(allPerson[i].number, tnum);
strcpy(allPerson[i].addr, taddr);
//打印测试
//printf("%s\n%s\n%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
//保证不会污染
memset(information, 0, 1024);
//下标后移
i++;
}
//printf("查找联系人姓名:\n");
//接收用户查找人信息
//char *temp = (char*)malloc(sizeof(char)*31);
//scanf("%s",temp);
fclose(file);
free(information);
information = NULL;
}
//查找联系人
void findContact() {
//获取联系人个数
int line = getContactLines();
//输入提示
printf("输入联系人姓名:\n");
//用户输入承载空间
char *findname = malloc(sizeof(char) * 31);
scanf("%s", findname);
//遍历对比
for (int i = 0; i < line; ++i) {
//strcmp对比,找到情况下
if (!strcmp(findname, allPerson[i].name)) {
printf("找到了\n");
printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
//页面暂停,阻塞,一个过滤回车,一个阻塞
printf("按任意键返回首页\n");
//system("pause");
getchar();
getchar();
return;
}
}
//未找到
printf("该联系人不存在\n");
//系统阻塞,一个过滤回车,一个阻塞
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
//添加联系人
void creatContact() {
//以只写权限打开文件
FILE *file = fopen("./Contact.txt", "a+");
if (!file)
return;
//存储信息中介,为了实现是否确认添加该联系人
person = (Contact *) malloc(sizeof(Contact));
person->name = (char *) malloc(sizeof(char) * 31);
person->number = (char *) malloc(sizeof(char) * 15);
person->addr = (char *) malloc(sizeof(char) * 51);
while (1) {
//用户输入信息
printf("在此输入姓名:\n");
scanf("%s", person->name);
printf("在此输入号码:\n");
scanf("%s", person->number);
printf("在此输入地址:\n");
scanf("%s", person->addr);
//用户确认是否添加该信息
printf("是否将此人添加至本地联系人列表?(是)Y/(否)N\n");
//过滤回车字符
getchar();
//确认字符接收
char sel;
scanf("%c", &sel);
//确认存储该信息,每个联系人信息占一行,用**隔开,便于提取
if (sel == 'Y') {
fputs(person->name, file);
fputs("#", file);
fputs(person->number, file);
fputs("#", file);
fputs(person->addr, file);
fputs("\n", file);
//联系人信息确认预览
printf("%s %s %s\n", person->name, person->number, person->addr);
//rewind(file);
//printf("%s%s%s",)
printf("已将联系人添加至本地库,是否继续?(是)Y/(否)N\n");
getchar();
scanf("%c", &sel);
//信息接收指针清零
memset(person->name, 0, 31);
memset(person->number, 0, 15);
memset(person->addr, 0, 51);
//继续添加联系人
if (sel == 'Y') {
fclose(file);
creatContact();
return;
}
//退出该功能
else if (sel == 'N') {
fclose(file);
printf("已退出添加联系人功能\n");
return;
}
//指令错误情况下退出该功能
else {
printf("指令有误,退出该功能\n");
fclose(file);
return;
}
}
//不添加该联系人信息
else if (sel == 'N') {
//询问是否继续
printf("已将此人记录销毁,是否继续?(是)Y/(否)N\n");
getchar();
scanf("%c", &sel);
//继续添加联系人,递归处理
if (sel == 'Y') {
fclose(file);
creatContact();
return;
}
//不再添加,则退出
else if (sel == 'N') {
fclose(file);
printf("已退出添加联系人功能\n");
return;
}
//指令错误处理
else {
printf("指令有误,退出该功能\n");
fclose(file);
return;
}
}
//用户首次进入该功能时,指令输入错误处理
else {
printf("已退出添加联系人功能\n");
fclose(file);
return;
}
}
}
//删除联系人
void deleteContact() {
loadContactFile();
//获取联系人个数
int line = getContactLines();
//输入提示
printf("输入联系人姓名:\n");
//用户输入承载空间
char *findname = malloc(sizeof(char) * 31);
scanf("%s", findname);
//遍历对比
for (int i = 0; i < line; ++i) {
//strcmp对比,找到情况下
if (!strcmp(findname, allPerson[i].name)) {
printf("找到了\n");
//再次确认
printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
printf("确认删除?无法恢复!(是)Y/(否)任意键\n");
//阻塞
getchar();
char sel;
//接收指令符
scanf("%c", &sel);
//确认删除
if (sel == 'Y') {
//重新载入文件,进行覆盖读写
FILE *fp = fopen("./Contact.txt", "w");
//char *information = (char*)malloc(sizeof(char)*1024);
//循环进行读写
for (int j = 0; j < line - 1; ++j) {
//过滤要删除的成员信息
if (i == j)
continue;
//重新写入文件
fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
}
//关闭文件以及提示
fclose(fp);
printf("该联系人已删除\n");
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
//用户查找到信息不想删除了,提示带阻塞
//页面暂停,阻塞,一个过滤回车,一个阻塞
printf("操作已撤销\n");
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
}
//用户输入姓名,未找到情况下
printf("未找到该联系人\n");
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
//修改联系人
void updateContact() {
//获取联系人个数
int line = getContactLines();
//输入提示
printf("输入联系人姓名:\n");
//用户输入承载空间
char *findname = malloc(sizeof(char) * 31);
scanf("%s", findname);
FILE *fp = fopen("./Contact.txt", "w");
//遍历对比
for (int i = 0; i < line; ++i) {
//strcmp对比,找到情况下
if (!strcmp(findname, allPerson[i].name)) {
printf("找到了\n");
printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
//提供选项
printf("输入要修改的内容选项:\n");
printf("1.姓名 2.号码 3.地址\n");
//阻塞
getchar();
//选项输入
int sel;
scanf("%d", &sel);
//临时指针空间
char *temp = malloc(sizeof(char) * 51);
//提示信息,并进行临时存储
printf("修改后的内容为:\n");
scanf("%s", temp);
//根据选项进行修改
switch (sel) {
case 1: {
strcpy(allPerson[i].name, temp);
for (int j = 0; j < line; j++) {
//重新写入文件
fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
}
printf("***修改成功***\n");
break;
}
case 2: {
strcpy(allPerson[i].number, temp);
for (int j = 0; j < line; j++) {
//重新写入文件
fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
}
printf("***修改成功***\n");
break;
}
case 3: {
strcpy(allPerson[i].addr, temp);
for (int j = 0; j < line; j++) {
//重新写入文件
fprintf(fp, "%s#%s#%s\n", allPerson[j].name, allPerson[j].number, allPerson[j].addr);
}
printf("***修改成功***\n");
break;
}
default:
printf("指令无效,已退出\n");
return;
}
//页面暂停,阻塞,一个过滤回车,一个阻塞
printf("是否继续修改?(是)Y,按任意键返回首页\n");
getchar();
getchar();
//继续选项
char csel;
scanf("%c", &csel);
if (csel == 'Y') {
fclose(fp);
updateContact();
return;
} else {
fclose(fp);
return;
}
}
}
//未找到
printf("该联系人不存在\n");
//系统阻塞,一个过滤回车,一个阻塞
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
//销毁通讯录文件(直接清空)
void destroyContact() {
//重点强调
printf("危险功能,确认密码:\n");
getchar();
int key;
scanf("%d", &key);
//核对密钥成功
if (key == 1234) {
printf("密码确认,开始清空...\n");
//与其说是销毁,就是对文件清空,利用'w'完成
FILE *fp = fopen("./Contact.txt", "w");
//实时关闭,以便刷新内容
fclose(fp);
printf("清空成功!后悔也晚了\n");
return;
}
//密钥错误,直接退出
else {
printf("密码不对,滚一边去\n");
return;
}
}
//查看所有联系人
void findAllContact() {
//加载
loadContactFile();
//获取联系人个数
int line = getContactLines();
//判断库文件是否有联系人
if (line <= 0) {
printf("本地库没有联系人,去添加吧!\n");
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
//遍历对比
for (int i = 0; i < line; ++i) {
printf("姓名:%s\n号码:%s\n地址:%s\n\n", allPerson[i].name, allPerson[i].number, allPerson[i].addr);
}
printf("*********联系人共%d名", line);
//页面暂停,阻塞,一个过滤回车,一个阻塞
printf("按任意键返回首页\n");
getchar();
getchar();
return;
}
//扫描本地通讯录文件,新建或者已存在返回1,文件不存在以及创建失败返回0
int scanContactFile() {
//搜索本地通讯录文件
FILE *fp = fopen("./Contact.txt", "r");
//通讯录文件不存在
if (!fp) {
//创建通讯录文件
printf("电脑中没有通讯录文件,是否创建?(是)Y/(否)N\n");
printf("请输入:\n");
char sel;
scanf("%c", &sel);
//一级:依据指令创建通讯录
if (sel == 'Y') {
//重新引导文件
fp = fopen("./Contact.txt", "w");
//文件创建失败
if (!fp) {
printf("抱歉,通讯录建立失败,请重新建立!\n");
return 0;
}
//成功提示
printf("通讯录已建立,请继续操作...\n");
return 1;
}
//一级:不创建通讯录
else if (sel == 'N') {
printf("未建立通讯录,无法继续操作!\n");
printf("再次确认是否创建通讯录文件?(是)Y/(否)N\n");
//系统阻塞(过滤回车)
getchar();
//接收指令
scanf("%c", &sel);
//二级:创建文件
if (sel == 'Y') {
//二级:重新引导文件
fp = fopen("./Contact.txt", "w");
//二级:文件引导失败
if (!fp) {
printf("抱歉,通讯录建立失败,请重新建立!\n");
return 0;
}
//二级:文件引导成功
printf("通讯录已建立,请继续操作...\n");
return 1;
}
//一级:文件引导失败
return 0;
}
//一级:指令错误情况下
else {
printf("输入无效选项,本次操作取消\n如需重新建立请输入\'Y\',输入其他字符将退出!\n");
//阻塞
getchar();
scanf("%c", &sel);
//二级:重新引导文件
if (sel == 'Y') {
fp = fopen("./Contact.txt", "w");
//二级:文件引导失败
if (!fp) {
printf("抱歉,通讯录建立失败,请重新建立!\n");
return 0;
}
//二级:文件引导成功
printf("通讯录已建立,请继续操作...\n");
return 1;
}
//二级:文件引导失败
else {
return 0;
}
}
}
//关闭文件,避免文件光标错乱,亦可使光标置于文件开头
fclose(fp);
//防止野指针
if (fp)
fp = NULL;
//通讯录文件已存在
return 1;
}
//选择对应功能进行操作
void selectFunction() {
int fun;
while (1) {
//载入首页
mainPage();
//扫描本地联系人文件
int ifo = scanContactFile();
if (!ifo) {
printf("Sorry,你不建立文件,我也没办法,再见\n");
return;
}
//提示信息
printf("输入要进行操作的序号:\n");
//接收用户选项
scanf("%d", &fun);
//程序退出指令
if (!fun) {
printf("退出成功\n");
return;
}
//加载
loadContactFile();
//进行选项
switch (fun) {
case 1:
findContact();
break;
case 2:
creatContact();
break;
case 3:
deleteContact();
break;
case 4:
updateContact();
break;
case 5:
destroyContact();
break;
case 6:
findAllContact();
break;
}
}
}
//释放全局指针空间
void freeSpace() {
if (person) {
free(person->name);
free(person->number);
free(person->addr);
free(person);
person = NULL;
}
if (allPerson) {
for (int i = 0; i < getContactLines(); ++i) {
free(allPerson[i].name);
free(allPerson[i].number);
free(allPerson[i].addr);
}
free(allPerson);
allPerson = NULL;
}
}
int main(void) {
selectFunction();
freeSpace();
return 0;
}