实现一个通讯录;
通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
提供方法:
- 添加联系人信息
- 删除指定联系人信息
- 查找指定联系人信息
- 修改指定联系人信息
- 显示所有联系人信息
- 清空所有联系人
- 以名字排序所有联系人
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//描述一个联系人信息
typedef struct PersonInfo {
char name[1024];
char phone[1024];
}PersonInfo;
#define MAX_SIZE 200
//使用数组组织若干个联系人信息
typedef struct AddressBook {
PersonInfo persons[MAX_SIZE];
int size;
int capacity; //数组当前的最大容量
}AddressBook;
//扩容
void ReallocPersons(AddressBook* addr_book) {
/*1.使用realloc
addr_book->capacity += 20;
addr_book->persons = PersonInfo * realloc(addre_book->persons,
addr_book->capacity * sizeof(PersonInfo));*/
//2.使用malloc
addr_book->capacity += 20;
//申请更大的内存空间
PersonInfo* newPersons = (PersonInfo*) malloc(addr_book->capacity * sizeof(PersonInfo));
(1)通过memcpy拷贝旧内存
memcpy(newPersons, addr_book->persons, addr_book->size * sizeof(PersonInfo));
/*(2)通过循环的方式来拷贝
for (inti = 0; i < addr_book->size; i++) {
strcpy(newPersons[i].name, addr_book->persons[i].name);
strcpy(newPersons[i].phone, addr_book->persons[i].phone);
//newPersons[i] = addr_book->persons[i];
}*/
free(addr_book->persons);
addr_book->persons = newPersons;
}
void save(AddressBook* addr_book) {
//通讯录中的所有数据保存到文件中
FILE* fp = fopen("d:/addr_book.txt", "w");
if (fp = NULL) {
perror("文件打开失败\n");
return;
}
//存数据
for (int i = 0; i < addr_book->size; i++) {
fwrite(&addr_book->persons[i], sizeof(PersonInfo), 1, fp);
}
fclose(fp);
printf("保存成功\n");
}
void load(AddressBook* addr_book) {
FILE* fp = fopen("d:/addr_book.txt", "r");
if (fp = NULL) {
perror("文件打开失败\n");
return;
}
PersonInfo tmp = { 0 };
while (1) {
int n = fread(&tmp, size(PersonInfo), 1, fp);
if (n < 1) {
break;
}
if (addr_book->size >= addr_book->capacity) {
ReallocPersons(addr_book);
}
addr_book->persons[addr_book - > size] = tmp;
addr_book->size++;
}
fclose(fp);
}
void Init(AddressBook* addr) {
//初始化通讯录结构体
addr->size = 0;
for (int i = 0; i < MAX_SIZE; i++) {
strcpy(addr->persons[i].name, "");
strcpy(addr->persons[i].phone, "");
}
}
int Menu() {
printf("=====================\n");
printf("1.新增联系人\n");
printf("2.删除联系人\n");
printf("3.查找联系人\n");
printf("4.修改联系人\n");
printf("5.打印全部联系人\n");
printf("6.清空全部联系人\n");
printf("0.退出\n");
printf("=====================\n");
printf("请输入您的选择: ");
int choice = 0;
scanf("%d", &choice);
return choice;
}
void AddPersonInfo(AddressBook* addr_book) {
printf("新增联系人\n");
if (addr_book->size >= MAX_SIZE) {
printf("通讯录已满,新增失败!\n");
return;
}
//核心代码
PersonInfo* info = &addr_book->persons[addr_book->size];
printf("请输入联系人姓名: ");
scanf("%s", info->name);
printf("请输入联系人电话: ");
scanf("%s", info->phone);
addr_book->size++;
printf("成功新增联系人\n");
}
void DelPersonInfo(AddressBook* addr_book) {
printf("执行删除操作\n");
if (addr_book->size <= 0) {
printf("通讯录为空,删除失败!\n");
return;
}
printf("请输入要删除联系人的序号: ");
int id = 0;
scanf("%d", &id);
//获取到最后一个元素
PersonInfo* last_info = &addr_book->persons[addr_book->size - 1];
//获取到待删除元素
PersonInfo* to_delete = &addr_book->persons[id];
//把最后一个元素赋值给待删除元素
*to_delete = *last_info;
addr_book->size--;
printf("成功删除联系人\n");
}
void FindPersonInfo(AddressBook* addr_book) {
printf("查找指定联系人\n");
printf("请输入要查找的联系人姓名\n");
char name[1024] = { 0 };
scanf("%s", name);
for (int i = 0; i < addr_book->size; i++) {
PersonInfo* info = &addr_book->persons[i];
if (strcmp(name, info->name) == 0) {
printf(" [%d] %s: %s", i, info->name, info->phone);
}
}
printf("成功查找联系人\n");
}
void ModifyPersonInfo(AddressBook* addr_book) {
//修改联系人内容,修改姓名或电话
if (addr_book->size <= 0) {
printf("通讯录为空,修改失败!\n");
return;
}
int id = 0;
printf("请输入要修改的联系人序号: ");
scanf("%d", &id);
if (id < 0 || id >= addr_book->size) {
printf("输入的序号非法,修改失败\n");
return;
}
PersonInfo* info = &addr_book->persons[id];
printf("请输入修改后的姓名(* 表示不变): ");
char name[1024] = { 0 };
scanf("%s", name);
if (strcmp(name, "*") != 0) {
strcpy(info->name, name);
}
printf("请输入修改后的电话(* 表示不变): ");
char phone[1024] = { 0 };
scanf("%s", phone);
if (strcmp(phone, "*") != 0) {
strcpy(info->phone, phone);
}
printf("修改成功\n");
}
void PrintAllPersonInfo(AddressBook* addr_book) {
for (int i = 0; i < addr_book->size; i++) {
PersonInfo* info = &addr_book->persons[i];
printf(" [%d] %s: %s\n", i, info->name, info->phone);
}
printf("当前共打印%d条记录\n", addr_book->size);
}
void ClearPersonInfo(AddressBook* addr_book) {
printf("删除全部记录!\n");
printf("您真的确定吗? Y/N\n");
char choice[1024] = { 0 };
if (strcmp(choice, "Y") == 0) {
addr_book->size = 0;
printf("删除成功\n");
return;
}
else {
printf("删除已经取消\n");
return;
}
}
int main() {
//此处可能存在风险
AddressBook address_book;
Init(&address_book);
//转移表
typedef void(*Func)(AddressBook*);
Func func_table[] = {
NULL,
AddPersonInfo,
DelPersonInfo,
FindPersonInfo,
ModifyPersonInfo,
PrintAllPersonInfo,
ClearPersonInfo,
};
while (1) {
//通过这个循环和用户进行交互
int choice = Menu();
if (choice < 0 || choice >= sizeof(func_table) / sizeof(func_table[0])) {
printf("您的输入有误\n");
continue;
}
if (choice == 0) {
printf("GOODBYE!\n");
break;
}
func_table[choice](&address_book);
}
//利用转移表更加简单清晰
/*if (choice == 0) {
printf("GOODBYE!\n");
break;
}
else if (choice == 1) {
AddPersonInfo(&address_book):
}
else if (choice == 2) {
DelProsonInfo(&address_book);
}
else if (choice == 3) {
FindPersonInfo(&address_book);
}
else if (choice == 4) {
ModifyPersonInfo(&address_book);
}
else if (choice == 5) {*/
/*PrintAllPersonInfo(&address_book);
}else if(choice == 6){
ClearPersonInfo(&address_book);
}
else {
printf("您的输入有误!\n");
}*/
system("pause");
return 0;
}