目录
前言
通讯录更新到3.0了!!!通讯录1.0是大数组版本,缺点是内存按需分配,通讯录2.0是动态内存版本,缺点是不能保存信息,现在这一版,完善了前两版的缺点。整体的实现思路请看我大数组版通讯录的博客https://blog.csdn.net/ZHENGZJM/article/details/128511139?spm=1001.2014.3001.5501https://blog.csdn.net/ZHENGZJM/article/details/128511139?spm=1001.2014.3001.5501
整段代码
类型的定义及函数的声明(头文件)
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//重定义最大名字,最大性别,最大电话,最大
#define MAX_NAME 100
#define MAX_SEX 100
#define MAX_TELE 100
#define MAX_PERSON 1000
#define MAX_ADDRESS 100
#define default_len 1
#define default_inc 2
//定以个人信息结构体
typedef struct perinf
{
char name[MAX_NAME];
char sex[MAX_SEX];
char tele[MAX_TELE];
char address[MAX_ADDRESS];
int age;
}perinf;
//定义通讯录类型
typedef struct contact
{
perinf* arr;
int sz;
int num;
}contact;
//定义菜单枚举类型
enum menu
{
EXIT,
ADD,
DEL,
SEEK,
MODIFY,
SORT,
DISPLAY
};
//定义查找内的菜单枚举类型
enum menu_seek
{
EXIT1,
NAME,
SEX,
TELE,
ADDRESS,
AGE
};
//定义排序菜单枚举类型
enum menu_sort
{
EXIT2,
SORTBYNAME,
SORTBYAGE
};
//声明打印菜单函数
void menu_print();
//声明菜单选择函数
void menu_option(int input, contact* p1);
//声明初始化通讯录函数
void Init_contact(contact* p1);
//声明添加联系人函数
void perinf_add(contact* p1);
//声明删除联系人函数
void perinf_del(contact* p1);
//声明遍历对比函数
int perinf_seek(contact* p1);
//声明查询函数
void perinf_SEEK(contact* p1);
//声明查找内的菜单函数
void menu_seek();
//声明查找内的菜单选择函数
void seekmenu_option(int a, int ret, contact* p1);
//声明修改函数
void perinf_MODIFY(contact* p1);
//声明显示通讯录函数
void perinf_dispay(contact* p1);
//声明排序菜单选择函数
void sortmenu_option(int a, contact* p1);
//声明排序菜单函数
void menu_sort();
//声明排序函数
void perinf_sort(contact* p1);
//扩容函数的声明
void capacity_expansion(contact* p1);
//销毁函数的声明
void Destroy(contact* p1);
//声明通讯录保存函数
void contact_save(contact* p1);
//声明加载函数
void load_file(contact* p1);
主体框架
打印菜单》用户选择》用户选择的实现,以及实现多次操作。
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
int main()
{
contact con;
Init_contact(&con);
int input = 0;
do
{
//打印菜单
menu_print();
printf("请选择您需要的功能:>\n");
scanf("%d", &input);
menu_option(input, &con);
} while (input);
return 0;
}
函数的实现
#include"contact.h"
//扩容函数
void capacity_expansion(contact* p1)
{
perinf* tmp = (perinf*)realloc(p1->arr, (p1->num+default_inc)* sizeof(perinf));
if (tmp != NULL)
{
p1->arr = tmp;
p1->num+=2;
printf("扩容成功!\n");
}
else
{
printf("扩容失败\n");
}
}
//声明加载函数
void load_file(contact* p1)
{
FILE* p = fopen("member_message.txt", "r");
if (p == NULL)
{
perror("fopen");
return;
}
else
{
perinf tmp = { 0 };
while (fread(&p1->arr[p1->sz], sizeof(perinf), 1, p))
{
capacity_expansion(p1);
p1->sz++;
}
}
fclose(p);
p = NULL;
}
//销毁函数
void Destroy(contact* p1)
{
free(p1->arr);
p1->arr = NULL;
p1->sz = 0;
p1->num = 0;
}
//初始化函数
void Init_contact(contact* p1)
{
perinf* tmp= (perinf*)malloc(default_len *sizeof(perinf));
if (tmp != NULL)
{
p1->arr = tmp;
}
else
{
printf("初始化内存开辟失败,请调整默认值");
}
p1->num = default_len;
p1->sz = 0;
//加载文件
load_file(p1);
}
//打印菜单函数
void menu_print()
{
printf("-------------------------------------\n");
printf("=====================================\n");
printf("=========1.添加 2.删除==========\n");
printf("=========3.查询 4.修改==========\n");
printf("=========5.排序 6.显示通讯录====\n");
printf("========= 0.退出 ==========\n");
printf("=====================================\n");
printf("-------------------------------------\n");
}
//查找内的菜单函数
void menu_seek()
{
printf("请选择要修改的内容\n");
printf("-------------------------------------\n");
printf("=====================================\n");
printf("=========1.姓名 2.性别==========\n");
printf("=========3.电话号码 4.家庭住址======\n");
printf("=========5.年龄 0.退出修改======\n");
printf("=====================================\n");
printf("-------------------------------------\n");
}
//查找内的菜单选择函数
void seekmenu_option(int a, int ret, contact* p1)
{
switch (a)
{
case NAME:
printf("请输入新姓名\n");
scanf("%s", p1->arr[ret].name);
printf("修改成功\n");
break;
case SEX:
printf("请输入新性别\n");
scanf("%s", p1->arr[ret].sex);
printf("修改成功\n");
break;
case TELE:
printf("请输入新电话号码\n");
scanf("%s", p1->arr[ret].tele);
printf("修改成功\n");
break;
case ADDRESS:
printf("请输入新家庭住址\n");
scanf("%s", p1->arr[ret].address);
printf("修改成功\n");
break;
case AGE:
printf("请输入新年龄\n");
scanf("%d", &p1->arr[ret].age);
printf("修改成功\n");
break;
case EXIT1:
printf("退出修改\n");
break;
default:
printf("请选择正确的选项\n");
break;
}
}
//菜单选择函数
void menu_option(int input, contact* p1)
{
switch (input)
{
case ADD:
system("cls");
printf("添加联系人\n");
perinf_add(p1);
break;
case DEL:
system("cls");
printf("删除联系人\n");
perinf_del(p1);
break;
case SEEK:
system("cls");
printf("查询联系人\n");
perinf_SEEK(p1);
break;
case MODIFY:
system("cls");
printf("修改联系人信息\n");
perinf_MODIFY(p1);
break;
case SORT:
system("cls");
printf("通讯录排序\n");
perinf_sort(p1);
break;
case DISPLAY:
system("cls");
printf("显示通讯录\n");
perinf_dispay(p1);
break;
case EXIT:
system("cls");
contact_save(p1);
Destroy(p1);
printf("退出成功,感谢使用。\n祝您生活美满,家庭幸福,身体健康\n");
break;
default:
printf("请重新选择正确的选项");
break;
}
}
//用户添加函数
void perinf_add(contact* p1)
{
if (p1->sz == p1->num)
{
capacity_expansion(p1);
}
printf("请输入姓名:>\n");
scanf("%s", p1->arr[p1->sz].name);
printf("请输入性别:>\n");
scanf("%s", p1->arr[p1->sz].sex);
printf("请输入电话号码:>\n");
scanf("%s", p1->arr[p1->sz].tele);
printf("请输入年龄:>\n");
scanf("%d", &(p1->arr[p1->sz].age));
printf("请输入家庭住址:>\n");
scanf("%s", p1->arr[p1->sz].address);
p1->sz++;
printf("添加成功QvQ\n");
return;
}
//查找函数
int perinf_seek(contact* p1)
{
int i = 0;
char brr[MAX_NAME] = { 0 };
perinf_dispay(p1);
printf("请输入要操作的人名:>\n");
scanf("%s", brr);
//遍历查找人名
for (i = 0; i < p1->sz; i++)
{
if ((strcmp(p1->arr[i].name, brr) == 0))
{
return i;
}
}
return -1;
}
//删除函数
void perinf_del(contact* p1)
{
if (p1->sz == 0)
{
printf("当前通讯录尚未存入联系人,无法删除\n");
return;
}
int ret = perinf_seek(p1);
if (ret == -1)
{
printf("查无此人,无法删除\n");
return;
}
else
{
memmove(&(p1->arr[ret]), &(p1->arr[ret + 1]), (long long)(p1->sz - ret) * sizeof(p1->arr[0]));
printf("删除成功\n");
p1->sz--;
return;
}
}
//查询函数
void perinf_SEEK(contact* p1)
{
int ret = perinf_seek(p1);
if (ret == -1)
{
printf("查无此人\n");
return;
}
else
{
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20s\n", "姓名", "性别", "电话号码", "家庭住址", "年龄");
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20d\n", p1->arr[ret].name, p1->arr[ret].sex, p1->arr[ret].tele, p1->arr[ret].address, p1->arr[ret].age);
return;
}
}
//修改函数
void perinf_MODIFY(contact* p1)
{
int ret = perinf_seek(p1);
if (ret == -1)
{
printf("查无此人\n");
return;
}
else
{
int a = 0;
do
{
menu_seek();
scanf("%d", &a);
seekmenu_option(a, ret, p1);
} while (a);
}
}
//显示整个通讯录函数
void perinf_dispay(contact* p1)
{
int i = 0;
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20s\n", "姓名", "性别", "电话号码", "家庭住址", "年龄");
for (i = 0; i < p1->sz; i++)
{
printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20d\n", p1->arr[i].name, p1->arr[i].sex, p1->arr[i].tele, p1->arr[i].address, p1->arr[i].age);
}
}
//排序函数
void perinf_sort(contact* p1)
{
int a = 0;
menu_sort();
printf("请选择排序方式\n");
scanf("%d", &a);
sortmenu_option(a, p1);
printf("排序完成\n");
}
//排序菜单函数
void menu_sort()
{
printf("请选择要修改的内容\n");
printf("-------------------------------------\n");
printf("=====================================\n");
printf("===1.按名字排序 2.按年龄排序===\n");
printf("=== 0.退出排序 ===\n");
printf("-------------------------------------\n");
}
//排序菜单选择函数
void sortmenu_option(int a, contact* p1)
{
int i = 0; int j = 0;
perinf tmp;
switch (a)
{
case SORTBYNAME:
for (i = 0; i < p1->sz; i++)
{
for (j = 0; j < p1->sz - 1; j++)
{
if (strcmp(p1->arr[j].name, p1->arr[j + 1].name) > 0)
{
tmp = p1->arr[j + 1];
p1->arr[j + 1] = p1->arr[j];
p1->arr[j] = tmp;
}
}
}
break;
case SORTBYAGE:
for (i = 0; i < p1->sz; i++)
{
for (j = 0; j < p1->sz - 1; j++)
{
if (p1->arr[j].age > p1->arr[j + 1].age)
{
tmp = p1->arr[j + 1];
p1->arr[j + 1] = p1->arr[j];
p1->arr[j] = tmp;
}
}
}
break;
case EXIT2:
{
printf("退出排序\n");
}
break;
default:
printf("请选择正确的选项\n");
break;
}
}
//通讯录保存函数
void contact_save(contact* p1)
{
int i = 0;
FILE* p=fopen("member_message.txt", "w");
if (p == NULL)
{
perror("fopen");
return;
}
else
{
for (i = 0; i < p1->sz; i++)
{
fwrite(p1->arr+i, sizeof(perinf),1, p);
}
fclose(p);
p = NULL;
}
printf("保存成功\n");
}
相较于动态内存版本的新增内容
通讯录信息保存函数
先打开文件,用“w”的原因是有则写入并且会覆盖掉原内容,无则创建再写入,先进行判断是否成功打开文件,然后使用fwrite进行写入。
//通讯录保存函数
void contact_save(contact* p1)
{
int i = 0;
FILE* p=fopen("member_message.txt", "w");
if (p == NULL)
{
perror("fopen");
return;
}
else
{
for (i = 0; i < p1->sz; i++)
{
fwrite(p1->arr+i, sizeof(perinf),1, p);
}
fclose(p);
p = NULL;
}
printf("保存成功\n");
}
文件加载函数
先打开文件并判断是否打开成功,然后利用fread函数进行读取,因为开始通讯录成员为零,记录通讯录成员的sz便也为零,随着信息的读入,sz会增加,这就需要判断要不要扩容,也就是用capactity_expansion函数来判断需不需要扩容,每读入一个信息sz就加一。
//加载函数
void load_file(contact* p1)
{
FILE* p = fopen("member_message.txt", "r");
if (p == NULL)
{
perror("fopen");
return;
}
else
{
perinf tmp = { 0 };
while (fread(&p1->arr[p1->sz], sizeof(perinf), 1, p))
{
capacity_expansion(p1);
p1->sz++;
}
}
fclose(p);
p = NULL;
}
总结
学校的管理系统大作业,本质就是实现增删查改,而通讯录也是需要增删查改的,所以说学会了通讯录就能轻松完成学校的管理系统大作业~希望能帮助到同志们。最终版本应该是用数据库的版本,等我再学完了之后再写博客