当前位置:网站首页>【C语言实现】----动态/文件/静态通讯录
【C语言实现】----动态/文件/静态通讯录
2022-07-26 18:09:00 【whispar】

作者 whispar
专栏 : C语言从无到有
放低姿态,空杯心态

目录
一、代码展示
test.c
使用枚举类型,使得菜单部分的代码可读性更强,便于理解
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
void menu() {
printf("*******\ 1.add 2.del /*******\n");
printf("*******\ 3.search 4.modify /*******\n");
printf("*******\ 5.show 6.sort /*******\n");
}
int main(){
int input = 0;
Contact con; //通讯录
//结构体传参
InitContact(&con); //结构体传参
do
{
menu();
printf("请选择:> ");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EXIT:
SaveContact(&con);
DestroyContact(&con);
printf("退出通讯录\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
contact.c
在contact.c中静态的版本无法满足我们的需求,因此我们在动态的版本当中使用realloc函数就可以做到对动态开辟内存大小,我们可以封装一个函数来判断容量是否足够,不够的话进行扩容。
在contact.c中文件的版本可以将创建的数据存储在本地,当程序退出时,数据依然存在,使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//静态的版本
//void InitContact(Contact* pc)
//{
// assert(pc);
// pc->count = 0;
// memset(pc->data, 0, sizeof(pc->data));
//}
void CheckCapacity(Contact* pc)
{
if (pc->count == pc->capacity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
if (ptr == NULL)
{
printf("AddContact::%s\n", strerror(errno));
return;
}
else
{
pc->data = ptr;
pc->capacity += INC_SZ;
printf("增容成功\n");
}
}
}
void LoadContact(Contact* pc)
{
FILE* pfRead = fopen("contact.txt", "rb");
if (pfRead == NULL)
{
perror("LoadContact");
return;
}
PeoInfo tmp = { 0 };
while (fread(&tmp, sizeof(PeoInfo), 1, pfRead) == 1)
{
CheckCapacity(pc);
pc->data[pc->count] = tmp;
pc->count++;
}
fclose(pfRead);
pfRead = NULL;
}
//动态的版本
int InitContact(Contact* pc)
{
assert(pc);
pc->count = 0;
pc->data = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
if (pc->data == NULL)
{
printf("InitContact::%s\n", strerror(errno));
return 1;
}
pc->capacity = DEFAULT_SZ;
//加载文件的信息到通讯录中
LoadContact(pc);
return 0;
}
void DestroyContact(Contact* pc)
{
assert(pc);
free(pc->data);
pc->data = NULL;
}
//静态的版本
//void AddContact(Contact* pc)
//{
// assert(pc);
// if (pc->count == MAX)
// {
// printf("通讯录已满,无法添加\n");
// return;
// }
// //
// printf("请输入名字:>");
// scanf("%s", pc->data[pc->count].name);
// printf("请输入年龄:>");
// scanf("%d", &(pc->data[pc->count].age));
// printf("请输入性别:>");
// scanf("%s", pc->data[pc->count].sex);
// printf("请输入电话:>");
// scanf("%s", pc->data[pc->count].tele);
// printf("请输入地址:>");
// scanf("%s", pc->data[pc->count].addr);
//
// pc->count++;
// printf("增加成功\n");
//}
//动态的版本
void AddContact(Contact* pc)
{
assert(pc);
//增容
CheckCapacity(pc);
//
printf("请输入名字:>");
scanf("%s", pc->data[pc->count].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pc->count].age));
printf("请输入性别:>");
scanf("%s", pc->data[pc->count].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pc->count].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->count].addr);
pc->count++;
printf("增加成功\n");
}
void ShowContact(const Contact* pc)
{
assert(pc);
int i = 0;
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
static int FindByName(Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (0 == strcmp(pc->data[i].name, name))
{
return i;
}
}
return -1;
}
void DelContact(Contact* pc)
{
char name[MAX_NAME] = { 0 };
assert(pc);
int i = 0;
if (pc->count == 0)
{
printf("通讯录为空,没有信息可以删除\n");
return;
}
printf("请输入要删除人的名字:>");
scanf("%s", name);
//删除
//1. 查找
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要删除的人不存在\n");
return;
}
//2. 删除
for (i = pos; i < pc->count - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;
printf("删除成功\n");
}
void SearchContact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要查找人的名字:>");
scanf("%s", name);
//1. 查找
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要查找的人不存在\n");
return;
}
//2. 打印
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
}
void ModifyContact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", name);
//1. 查找
int pos = FindByName(pc, name);
if (pos == -1)
{
printf("要修改的人不存在\n");
return;
}
printf("要修改的人的信息已经查找到,接下来开始修改\n");
//2. 修改
printf("请输入名字:>");
scanf("%s", pc->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pos].age));
printf("请输入性别:>");
scanf("%s", pc->data[pos].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pos].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pos].addr);
printf("修改成功\n");
}
int cmp_peo_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
//按照名字来排序
void SortContact(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_peo_by_name);
printf("排序成功\n");
}
void SaveContact(const Contact* pc)
{
assert(pc);
FILE* pfWrite = fopen("contact.txt", "wb");
if (pfWrite == NULL)
{
perror("SaveContact");
return;
}
//写文件-二进制的形式
int i = 0;
for (i = 0; i < pc->count; i++)
{
fwrite(pc->data + i, sizeof(PeoInfo), 1, pfWrite);
}
fclose(pfWrite);
pfWrite = NULL;
}
contact.h
#pragma once
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#define DEFAULT_SZ 3
#define INC_SZ 2
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30
//类型的声明
//
//人的信息
typedef struct PeoInfo
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
} PeoInfo;
//通讯录
//静态版本
//typedef struct Contact
//{
// PeoInfo data[MAX];//存放人的信息
// int count;//记录当前通讯录中实际人的个数
//}Contact;
//动态的版本
typedef struct Contact
{
PeoInfo* data;//存放人的信息
int count;//记录当前通讯录中实际人的个数
int capacity;//当前通讯录的容量
}Contact;
//初始化通讯录
int InitContact(Contact* pc);
//销毁通讯录
void DestroyContact(Contact* pc);
//增加联系人都通讯录
void AddContact(Contact* pc);
//打印通讯中的信息
void ShowContact(const Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//查找指定联系人
void SearchContact(Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//排序通讯录中内容
//按照名字来排序
//按照年龄来排序
//...
void SortContact(Contact* pc);
//保存通讯录的信息到文件
void SaveContact(const Contact* pc);
//加载文件的信息到通讯录
void LoadContact(Contact* pc);
二、效果展示
静态版本基本功能的实现



动态版本扩容功能的实现

文件版本保存本地功能实现

如果文章对你有帮助,请多多点赞、收藏、评论、关注支持!!

边栏推荐
- MySQL日志介绍
- The class jointly built by famous oarsmen is new, and Professor qiuxipeng of Fudan University broadcast it live on Tuesday!
- 深度学习的数学基础
- 手机申请公募reits账户安全吗?
- Tensorflow GPU 1.15 installation
- Multi thread learning notes -1.cas
- Leetcode notes: biweekly contest 83
- MySQL log introduction
- Tensor Rt的int8量化原理
- After the exam on June 25, see how the new exam outline reviews PMP
猜你喜欢

VTK (the Visualization Toolkit) loads STL models

2022t elevator repair examination questions and online simulation examination

This article explains in detail the five benefits that MES system brings to enterprises, with application scenarios

篇7:exited on DESKTOP-DFF5KIK with error code -1073741511.

MySQL - 多表查询与案例详解

【MySQL从入门到精通】【高级篇】(八)聚簇索引&非聚簇索引&联合索引

MySQL log introduction

PMP practice once a day | don't get lost in the exam -7.26 (including agility + multiple choices)

SD NAND与eMMC优劣势对比

Redis学习笔记-2.客户端的使用
随机推荐
支持代理直连Oracle数据库,JumpServer堡垒机v2.24.0发布
CTO will teach you: how to take over his project when a technician suddenly leaves
Tensor Rt的int8量化原理
LeetCode简单题之装满杯子需要的最短总时长
rancher部署kubernetes集群
【MySQL从入门到精通】【高级篇】(八)聚簇索引&非聚簇索引&联合索引
简述MES系统的11大核心功能模块
Utility website recommendations
VPC nat (Sant, nant) experiment
Some time series modeling strategies (I)
2022年流动式起重机司机考试试题模拟考试平台操作
MongoDB stats统计集合占用空间大小
In this competition, you who can understand the topic have great potential
MySQL - function and constraint commands
手机申请公募reits账户安全吗?
Reentrantlock learning - lock release process
The class jointly built by famous oarsmen is new, and Professor qiuxipeng of Fudan University broadcast it live on Tuesday!
The first letter of leetcode simple question appears twice
Seata 入门简介
Mathematical basis of deep learning