1.通讯人数据的导入和存储
我们希望联系人的数据可以长久的保留那么我们可以通过文件操作去保存我们联系人的数据到文件中,创建一个储存联系人数据的文件:contacts.txt , 通过这个文件我们将保存联系人数据
文件的读取
我们将contacts.txt里的联系人数据导出到程序中,以便后续的操作
//先要加载数据FILE* pf;pf = fopen("contacts.txt", "r");if (pf == NULL) {perror("fopen");return 0;}//读取文件里的联系人信息int cont = 1;while (1){peoInfo info;cont = fscanf(pf, "%s %s %d %s %s ",info.name,info.sex,&info.age,info.tel,info.addr);//成功加载一个联系人就放进通讯录if (cont > 0){ContactPushBack(&con, info);}if (cont <= 0){break;}}//关闭文件fclose(pf);pf = NULL;
将修改后的练习数据存储至文件中
//输出联系人信息到文件//以写的方式打开contacts.txt文件pf = fopen("contacts.txt", "w");if (pf == NULL) {perror("fopen");return 0;}//con是我们的通讯录结构体,size是通讯录中有效的联系人数据 if (con.size >= 0){//把联系人数据依次加载进文件中for (int i = 0; i < con.size; i++){fprintf(pf, "%s %s %d %s %s ",con.arr[i].name,con.arr[i].sex,con.arr[i].age,con.arr[i].tel,con.arr[i].addr);}}//关闭文件fclose(pf);pf = NULL;
2.通讯录结构体的创建
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100//通讯录结构体
typedef struct contact {SLDataType* arr;int size; //有效数据int capacity; //空间大小
}contact;//定义联系人结构体
typedef struct personInfo {char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;//把将要存到通讯录里的数据类型换成联系人结构体
typedef peoInfo SLDataType;
3.通讯录各种功能的实现
通讯录的初始化
//初始化通讯录void InitContact(contact* con) {assert(con);con->arr = NULL;con->capacity = con->size = 0;
}
通讯录的销毁
//销毁通讯录数据void DestroyContact(contact* con) {assert(con);if (con->arr) //如果通讯录不为空,则销毁通讯录{free(con->arr);}con->arr = NULL;con->capacity = con->size = 0;
}
对通讯录进行扩容
如果联系人的数据把通讯录占满了,我们就需要对通讯录进行扩容
//对通讯录进行扩容void ContactCheckCapacity(contact* con) {assert(con);//有效数据和空间大小一样,就代表空间满了,开始扩容if (con->size == con->capacity){int newcapacity;SLDataType* newps;//如果一开始没有空间,就给它一个空间,否则空间就*2倍增长newcapacity = con->capacity == 0 ? 4 : con->capacity * 2;//开辟新的空间newps = (SLDataType*)realloc(con->arr, newcapacity * sizeof(SLDataType));//判断新的空间有没有开辟成功if (newps == NULL){perror("realloc");exit(1);}con->arr = newps;con->capacity = newcapacity;}}
添加联系人数据
//添加联系人数据void AddContact(contact* con) {peoInfo info;printf("请输入要添加的联系人姓名\n");scanf("%s", info.name);printf("请输入要添加的联系人性别\n");scanf("%s", info.sex);printf("请输入要添加的联系人年龄\n");scanf("%d", &info.age);printf("请输入要添加的联系人电话\n");scanf("%s", info.tel);printf("请输入要添加的联系人住址\n");scanf("%s", info.addr);//先判断空间是不是满了,要不要扩容ContactCheckCapacity(con);//进行添加数据con->arr[con->size++] = info;
}
删除联系人数据
//删除联系人数据void DelContact(contact* con) {assert(con);char name[NAME_MAX];printf("请输入要删除联系人的姓名\n");scanf("%s", name);int pos = Findname(con, name);//不能删除没有数据的地方assert(pos >= 0 && pos < con->size);for (int i = pos; i < con->size - 1; i++){con->arr[i] = con->arr[i + 1];}con->size--;
}
返回联系人姓名下标
//返回联系人姓名下标
int Findname(contact* con, char name[NAME_MAX]) {for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){return i;}}return -1;
}
查找联系人数据
//查找联系人数据void FindContact(contact* con) {char name[NAME_MAX];printf("请输入要查找的联系人姓名:\n");scanf("%s", name);int i = Findname(con, name);if (i >= 0){printf("姓名\t性别\t年龄\t电话\t\t住址\n");printf("%-8s%-8s%-8d%-16s%-20s\n",con->arr[i].name,con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);return;}printf("没有此联系人!");
}
修改联系人数据
//修改联系人数据void ModifyContact(contact* con) {char name[NAME_MAX];printf("请输入要修改的联系人姓名\n");scanf("%s", name);int pos = Findname(con, name);if (pos >= 0) {printf("此人存在开始修改!\n");printf("请输入要修改的联系人姓名\n");scanf("%s", con->arr[pos].name);printf("请输入要修改的联系人性别\n");scanf("%s", con->arr[pos].sex);printf("请输入要修改的联系人年龄\n");scanf("%d", &con->arr[pos].age);printf("请输入要修改的联系人电话\n");scanf("%s", con->arr[pos].tel);printf("请输入要修改的联系人住址\n");scanf("%s", con->arr[pos].addr);printf("修改完成!\n");return;}printf("没有此人信息!");
}
展示联系人数据
//展示通讯录数据void ShowContact(contact* con) {printf("姓名\t性别\t年龄\t电话\t\t住址\n");for (int i = 0; i < con->size; i++){printf("%-8s%-8s%-8d%-16s%-20s\n",con->arr[i].name,con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
查找联系人数据
//查找联系人数据void FindContact(contact* con) {char name[NAME_MAX];printf("请输入要查找的联系人姓名:\n");scanf("%s", name);int pos = Findname(con, name);if (pos >= 0){printf("姓名\t性别\t年龄\t电话\t\t住址\n");printf("%-8s%-8s%-8d%-16s%-20s\n",con->arr[pos].name,con->arr[pos].sex,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);return;}printf("没有此联系人!");
}
4.通讯录项目实现全代码
项目主要逻辑
void menu() {printf("-----------通讯录-----------\n");printf("--------0.退出通讯录--------\n");printf("--------1.添加联系人--------\n");printf("--------2.删除联系人--------\n");printf("--------3.修改联系人--------\n");printf("--------4.查找联系人--------\n");printf("--------5.展示通讯录--------\n");printf("-----------通讯录-----------\n");
}
int main() {int op = 0;contact con;InitContact(&con);//先要加载数据FILE* pf;pf = fopen("contacts.txt", "r");if (pf == NULL) {perror("fopen");return 0;}//读取文件里的联系人信息int cont = 1;while (1){peoInfo info;cont = fscanf(pf, "%s %s %d %s %s ",info.name,info.sex,&info.age,info.tel,info.addr);//成功加载一个联系人就放进通讯录if (cont > 0){ContactPushBack(&con, info);}if (cont <= 0){break;}}//关闭文件fclose(pf);pf = NULL;do {menu();printf("请选着您想进行的操作\n");scanf("%d", &op);switch (op){case 0:system("cls");printf("退出通讯录\n");break;case 1:system("cls");AddContact(&con);break;case 2:system("cls");DelContact(&con);break;case 3:system("cls");ModifyContact(&con);break;case 4:system("cls");FindContact(&con);break;case 5:system("cls");ShowContact(&con);break;default:system("cls");printf("输入错误!请重新输入\n");break;}} while (op);//输出联系人信息到文件pf = fopen("contacts.txt", "w");if (pf == NULL) {perror("fopen");return 0;}if (con.capacity >= 0){for (int i = 0; i < con.size; i++){fprintf(pf, "%s %s %d %s %s ",con.arr[i].name,con.arr[i].sex,con.arr[i].age,con.arr[i].tel,con.arr[i].addr);}}//关闭文件fclose(pf);pf = NULL;DestroyContact(&con);return 0;
}
Contact.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include <string.h>
#include <windows.h>#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100//定义联系人结构体
typedef struct personInfo {char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}peoInfo;//把将要存到通讯录里的数据类型换成联系人结构体
typedef peoInfo SLDataType;//通讯录表结构体
typedef struct contact {SLDataType* arr;int size; //有效数据int capacity; //空间大小
}contact;//初始化通讯录void InitContact(contact* con);//对通讯录进行扩容
void ContactCheckCapacity(contact* con);//添加联系人数据void AddContact(contact* con);//删除联系人数据void DelContact(contact* con);//展示联系人数据void ShowContact(contact* con);//返回联系人姓名下标
int Findname(contact* con, char name[NAME_MAX]);//查找联系人数据void FindContact(contact* con);//修改联系人数据void ModifyContact(contact* con);//销毁通讯录数据void DestroyContact(contact* con);//尾部插入数据
void ContactPushBack(contact* con, SLDataType x);
Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Comtact.h"
//初始化通讯录void InitContact(contact* con) {assert(con);con->arr = NULL;con->capacity = con->size = 0;
}//对通讯录进行扩容void ContactCheckCapacity(contact* con) {assert(con);//有效数据和空间大小一样,就代表空间满了if (con->size == con->capacity){int newcapacity;SLDataType* newps;//如果一开始没有空间,就给它一个空间,否则空间就*2倍增长newcapacity = con->capacity == 0 ? 4 : con->capacity * 2;//开辟新的空间newps = (SLDataType*)realloc(con->arr, newcapacity * sizeof(SLDataType));//判断新的空间有没有开辟成功if (newps == NULL){perror("realloc");exit(1);}con->arr = newps;con->capacity = newcapacity;}}//添加联系人数据void AddContact(contact* con) {peoInfo info;printf("请输入要添加的联系人姓名\n");scanf("%s", info.name);printf("请输入要添加的联系人性别\n");scanf("%s", info.sex);printf("请输入要添加的联系人年龄\n");scanf("%d", &info.age);printf("请输入要添加的联系人电话\n");scanf("%s", info.tel);printf("请输入要添加的联系人住址\n");scanf("%s", info.addr);//先判断空间是不是满了,要不要扩容ContactCheckCapacity(con);//进行添加数据con->arr[con->size++] = info;
}//返回联系人姓名下标
int Findname(contact* con, char name[NAME_MAX]) {for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){return i;}}return -1;
}//删除联系人数据void DelContact(contact* con) {assert(con);char name[NAME_MAX];printf("请输入要删除联系人的姓名\n");scanf("%s", name);int pos = Findname(con, name);//不能删除没有数据的地方assert(pos >= 0 && pos < con->size);for (int i = pos; i < con->size - 1; i++){con->arr[i] = con->arr[i + 1];}con->size--;
}//展示联系人数据void ShowContact(contact* con) {printf("姓名\t性别\t年龄\t电话\t\t住址\n");for (int i = 0; i < con->size; i++){printf("%-8s%-8s%-8d%-16s%-20s\n",con->arr[i].name,con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}//查找联系人数据void FindContact(contact* con) {char name[NAME_MAX];printf("请输入要查找的联系人姓名:\n");scanf("%s", name);int pos = Findname(con, name);if (pos >= 0){printf("姓名\t性别\t年龄\t电话\t\t住址\n");printf("%-8s%-8s%-8d%-16s%-20s\n",con->arr[pos].name,con->arr[pos].sex,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);return;}printf("没有此联系人!");
}//修改联系人数据void ModifyContact(contact* con) {char name[NAME_MAX];printf("请输入要修改的联系人姓名\n");scanf("%s", name);int pos = Findname(con, name);if (pos >= 0) {printf("此人存在开始修改!\n");printf("请输入要修改的联系人姓名\n");scanf("%s", con->arr[pos].name);printf("请输入要修改的联系人性别\n");scanf("%s", con->arr[pos].sex);printf("请输入要修改的联系人年龄\n");scanf("%d", &con->arr[pos].age);printf("请输入要修改的联系人电话\n");scanf("%s", con->arr[pos].tel);printf("请输入要修改的联系人住址\n");scanf("%s", con->arr[pos].addr);printf("修改完成!\n");return;}printf("没有此人信息!");
}//销毁通讯录数据void DestroyContact(contact* con) {assert(con);if (con->arr){free(con->arr);}con->arr = NULL;con->capacity = con->size = 0;
}//尾部插入数据
void ContactPushBack(contact* con, SLDataType x) {assert(con);ContactCheckCapacity(con);con->arr[con->size++] = x;
}