终极版的通讯录(文件版)

一、前言

简单版的通讯录(静态版)
改进版的通讯录(动态版)

二、改进思路 

无论是静态版本,还是动态版本的通讯录,数据都是放在内存中的,因此当程序退出后,通讯录中的数据就不存在了。
当需要将数据持久化时,就可以使用文件相关的操作(万字详解 C 语言文件操作)。

三、 test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void menu()
{
	printf("********************************\n");
	printf("***** 1. Add     2. Del    *****\n");
	printf("***** 3. Search  4. Modify *****\n");
	printf("***** 5. Show    6. Sort   *****\n");
	printf("***** 7. Cls     0. Exit   *****\n");
	printf("********************************\n");
}

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	CLS
};

int main()
{
	int input = 0;
	Contact con;
	ContactInit(&con);
	ContactLoad(&con);
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			ContactAdd(&con);
			break;
		case DEL:
			ContactDel(&con);
			break;
		case SEARCH:
			ContactSearch(&con);
			break;
		case MODIFY:
			ContactModify(&con);
			break;
		case SHOW:
			ContactShow(&con);
			break;
		case SORT:
			ContactSort(&con);
			break;
		case CLS:
			system("cls");
			break;
		case EXIT:
			ContactSave(&con);
			// 使用了动态开辟的内存,就需要主动释放
			free(con.data);
			con.data = NULL;;
			printf("退出通讯录~\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);
	return 0;
}

四、contact.h

#pragma once

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define DEFAULT_SIZE  5 // 容量的默认大小
#define INCREMENT 5  // 扩容的增量


// 类型的声明
typedef struct PeoInfo
{
	char name[20];
	int age;
	char gender[10];
	char addr[20];
	char tel[15];
}PeoInfo;

typedef struct Contact
{
	PeoInfo* data;
	int count;  // 不仅能表示当前通讯录中的人数,还能表示能存放联系人信息的数组下标
	int capacity;  // 容量,即表示当前通讯录最多能存放多少联系人的信息
}Contact;


// 函数的声明
void ContactInit(Contact* pc);  // 初始化通讯录

void ContactLoad(Contact* pc);  // 加载通讯录的数据

void ContactShow(const Contact* pc);  // 5 - 显示所有的联系人

void ContactAdd(Contact* pc);  // 1 - 添加联系人

void ContactDel(Contact* pc);  // 2 - 删除联系人

void ContactSearch(const Contact* pc);  // 3 - 查找联系人

void ContactModify(Contact* pc);  // 4 - 修改联系人

void ContactSort(Contact* pc);  // 6 - 对通讯录进行排序(按名字进行排序)

void ContactSave(Contact* pc);  // 保存通讯录

五、contact.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"


// 初始化通讯录
void ContactInit(Contact* pc)
{
	pc->count = 0;
	pc->capacity = DEFAULT_SIZE;
	pc->data = (PeoInfo*)calloc(pc->capacity, sizeof(PeoInfo));
	if (NULL == pc->data)
	{
		perror("Initialization failed!");
		exit(1);
	}
}


// 加载通讯录的数据
void ContactLoad(Contact* pc)
{
	FILE* fp = fopen("contact.txt", "rb");
	if (NULL == fp)
	{
		perror("Load failed for fopen!");
		exit(1);
	}
	PeoInfo tmp = { 0 };
	for (int i = 0; fread(&tmp, sizeof(PeoInfo), 1, fp); i++)
	{
		if (pc->count == pc->capacity)
		{
			PeoInfo* ret = (PeoInfo*)realloc(pc->data, (pc->capacity + INCREMENT) * sizeof(PeoInfo));
			if (NULL == ret)
			{
				perror("Load failed for realloc!");
				exit(1);
			}
			pc->data = ret;
			pc->capacity += INCREMENT;
			ret = NULL;
		}
		pc->data[i] = tmp;
		pc->count++;
	}
	fclose(fp);
	fp = NULL;
}


// 5 - 显示所有的联系人
void ContactShow(const Contact* pc)
{
	printf("%-20s %-4s %-10s %-20s %-15s\n", "姓名", "年龄", "性别", "家庭住址", "电话号码");
	for (int i = 0; i < pc->count; i++)
	{
		printf("%-20s %-4d %-10s %-20s %-15s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].gender,
			pc->data[i].addr,
			pc->data[i].tel
		);
	}
}


// 1 - 添加联系人
void ContactAdd(Contact* pc)
{
	if (pc->count == pc->capacity)
	{
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + INCREMENT) * sizeof(PeoInfo));
		if (NULL == tmp)
		{
			printf("扩容失败,无法再添加联系人!\n");
			return;
		}
		pc->data = tmp;
		pc->capacity += INCREMENT;
		tmp = NULL;
	}
	printf("请输入联系人的姓名:>");
	scanf("%s", pc->data[pc->count].name);
	printf("请输入联系人的年龄:>");
	scanf("%d", &pc->data[pc->count].age);
	printf("请输入联系人的性别:>");
	scanf("%s", pc->data[pc->count].gender);
	printf("请输入联系人的家庭住址:>");
	scanf("%s", pc->data[pc->count].addr);
	printf("请输入联系人的电话号码:>");
	scanf("%s", pc->data[pc->count].tel);
	pc->count++;
	printf("添加成功~\n");
}


// 通过联系人的姓名找到其在数组中对应的下标
static FindByName(const Contact* pc, char name[])
{
	for (int i = 0; i < pc->count; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}


// 2 - 删除联系人
void ContactDel(Contact* pc)
{
	if (pc->count == 0)
	{
		printf("通讯录为空!\n");
		return;
	}
	char name[20];
	printf("请输入待删除的联系人的姓名:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("该联系人不存在!\n");
		return;
	}
	else
	{
		for (int i = pos + 1; i < pc->count; i++)
		{
			pc->data[i - 1] = pc->data[i];
		}
		pc->count--;
		printf("删除成功~\n");
	}
}


// 3 - 查找联系人
void ContactSearch(const Contact* pc)
{
	char name[20];
	printf("请输入待查找的联系人的姓名:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("该联系人不存在!\n");
		return;
	}
	else
	{
		printf("%-20s %-4s %-10s %-20s %-15s\n", "姓名", "年龄", "性别", "家庭住址", "电话号码");
		printf("%-20s %-4d %-10s %-20s %-15s\n",
			pc->data[pos].name,
			pc->data[pos].age,
			pc->data[pos].gender,
			pc->data[pos].addr,
			pc->data[pos].tel
		);
	}
}


// 4 - 修改联系人
void ContactModify(Contact* pc)
{
	char name[20];
	printf("请输入待修改的联系人的姓名:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("该联系人不存在!\n");
		return;
	}
	else
	{
		printf("请重新输入该联系人的姓名:>");
		scanf("%s", pc->data[pos].name);
		printf("请重新输入该联系人的年龄:>");
		scanf("%d", &pc->data[pos].age);
		printf("请重新输入该联系人的性别:>");
		scanf("%s", pc->data[pos].gender);
		printf("请重新输入该联系人的家庭住址:>");
		scanf("%s", pc->data[pos].addr);
		printf("请重新输入该联系人的电话号码:>");
		scanf("%s", pc->data[pos].tel);
		printf("修改成功~\n");
	}
}


// 6 - 按联系人的姓名对通讯录进行排序
int cmp_by_name(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}

void ContactSort(Contact* pc)
{
	qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
	printf("排序成功~\n");
}


// 保存通讯录
void ContactSave(Contact* pc)
{
	FILE* fp = fopen("contact.txt", "wb");
	if (NULL == fp)
	{
		perror("Save failed!");
		return;
	}
	for (int i = 0; i < pc->count; i++)
	{
		fwrite(pc->data + i, sizeof(PeoInfo), 1, fp);
	}
	fclose(fp);
	fp = NULL;
	printf("通讯录已保存~\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EML企业通讯录管理系统 v5.4.14更新日志 1、修复页面显示问题。 2、修复BUG,后台参数过滤提高安全性; 3、优化数据库结构,提高列表查询速度; EML企业通讯录管理系统简介 企业通讯录管理系统,向企业员工随时随地的提供企业通讯录信息,用户可在手机端实时查看人员联系方式,拨打电话等全面提高了企业内部沟通效率。 主要功能有:用户管理(添加用户,删除用户用户,更新用户资料);通讯录管理(添加通讯录,更新通讯录,删除),个人中心,配置管理等。 EML企业客户关系管理系统,是基于Linux开放性内核和Apache基础上Php Mysql的智能B/S交互式服务系统。 EML系统移动端由移动端采用javascript、html5、ajax、json等技术。 中间件层包括函数库,由java开发,android操作系统、中间件、用户界面和应用软件组成。 最佳分辨率: 1440x900 最佳浏览器: 火狐Firefox EML企业通讯录管理系统功能描述: 1.用户管理 2.通讯录管理: 3.角色管理: 4.个人中心 5.配置管理 EML企业通讯录管理系统目录说明: ./action 执行文件目录 ./css 样式目录 ./img 图片目录 ./js 脚本目录 ./lib 类文件及配置文件 ./tpl 网页模目录 ./index.php 首页文件,网站配置信息 ./m.php MD5加密测试文件 ./contacts.sql 数据库文件 EML企业通讯录管理系统使用说明: 1.数据库文件 contacts.sql (提前创建mysql数据库,并导入此数据) 2.数据库配置入口文件index.php(数据库配置相关信息) 3.访问地址 http://127.0.0.1/ (如果放在网站根目录的话) 4.首页路径 ./ 5.默认普通用户konghong密码123456,管理员用户:admin 密码:admin EML企业通讯录管理系统使用技巧: 配置文件: ./lib/cfg.class.php 1.数据库配置 通过修改配置文件 2.管理员帐号密码 通过修改配置文件 EML企业通讯录管理系统登录界面 EML企业通讯录管理系统后台管理 后台路径:域名/index.php 管理员用户:admin 密码:admin 后台页面:   相关阅读 同类推荐:OA系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值