【C进阶】- 通讯录

静态版本

所谓静态版本,就是大小是确定的,比如曾经的老年机的通讯录存储容量

  • test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
//添加联系人信息
//删除指定联系人信息
//查找指定联系人信息
//修改指定联系人信息
//显示所有联系人信息
//清空所有联系人
//以名字排序所有联系人


//利用枚举让我们更加直观的看到各个case的作用,即使很久之后
enum Option
{
	EXIT,
	ADD,
	DELETE,
	SEARCH,
	MODIFY,
	SORT,
	SHOW,
	EMPTY,
};

void menu()
{
	printf("******************************\n");
	printf("****  1.Add     2.Del     ****\n");
	printf("****  3.search  4.modify  ****\n");
	printf("****  5.sort    6.show    ****\n");
	printf("****  7.empty   0.exit    ****\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	Contact con = { 0 };
	InitContact(&con);//初始化通讯录
	do 
	{
		menu();
		printf("请选择:->");
		scanf_s("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DELETE:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModfityContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case EMPTY:
			EmptyContact(&con);
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择:\n");
			break;
		}
	} while (input);

	return 0;
}
  • contact.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->date, 0, sizeof(pc->date));
}

void AddContact(Contact* pc)
{
	//1.判断是否为空
	assert(pc);
	//2.是否需要扩容
	if (pc->sz == MAX)
	{
		printf("通讯录已满,添加失败\n");
		return;
	}
	printf("请输入联系人名字:");
	scanf("%s", pc->date[pc->sz].name);

	printf("请输入联系人性别:");
	scanf("%s", pc->date[pc->sz].sex);

	printf("请输入联系人年龄:");
	scanf("%d", &(pc->date[pc->sz].age));

	printf("请输入联系人电话号码:");
	scanf("%s", pc->date[pc->sz].tele);

	printf("请输入联系人地址:");
	scanf("%s", pc->date[pc->sz].addr);

	pc->sz++;
	printf("添加成功!\n");
}


void ShowContact(const Contact* pc)
{
	assert(pc);
	printf("%-15s\t%-5s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0;i < pc->sz; i++)
	{
		printf("%-15s\t%-5s\t%-5d\t%-15s\t%-20s\n", 
			pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	for (int i = 0;i < pc->sz; i++)
	{
		if (strcmp(pc->date[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}


void DeleteContact(Contact* pc) 
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	//通讯录为空,无法删除
	if (pc->sz == 0)
	{
		printf("通讯录为空,删除失败!\n");
		return;
	}
	printf("请输入删除联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在!\n");
		return;
	}
	else
	{
		for (int i = 0;i < pc->sz - 1;i++)
		{
			pc->date[i] = pc->date[i + 1];
		}
		pc->sz--;
		printf("删除成功!\n");
	}
}


void SearchContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,查找失败!\n");
		return;
	}
	printf("请输入查找联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在,查找失败!\n");
		return;
	}
	else
	{
		printf("查找成功信息如下:\n");
		printf("%-15s\t%-5s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-15s\t%-5s\t%-5d\t%-15s\t%-20s\n",
			pc->date[Index].name, pc->date[Index].sex,
			pc->date[Index].age, pc->date[Index].tele, pc->date[Index].addr);
	}
}


void ModfityContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,修改失败!\n");
		return;
	}
	printf("请输入修改联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在,查找失败!\n");
		return;
	}
	else
	{
		printf("请输入修改后联系人名字:");
		scanf("%s", pc->date[pc->sz].name);

		printf("请输入修改后联系人性别:");
		scanf("%s", pc->date[pc->sz].sex);

		printf("请输入修改后联系人年龄:");
		scanf("%d", &(pc->date[pc->sz].age));

		printf("请输入修改后联系人电话号码:");
		scanf("%s", pc->date[pc->sz].tele);

		printf("请输入修改后联系人地址:");
		scanf("%s", pc->date[pc->sz].addr);

		printf("修改成功!\n");
	}
}
int cmp_byname(const void* e1, const void* e2)
{
	return strcmp(((Contact*)e1)->date->name, ((Contact*)e2)->date->name);
}

void SortContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,排序失败!\n");
		return;
	}
	qsort(pc->date, pc->sz, sizeof(pc->date[0]), cmp_byname);
	printf("排序成功!\n");
}

void EmptyContact(Contact* pc)
{
	InitContact(pc);
	printf("清空成功!\n");
}

  • contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

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

#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12

#define MAX 20


typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo date[MAX];
	int sz;
}Contact;

//初始化通讯录
void InitContact(Contact *pc);

//增加联系人信息
void AddContact(Contact* pc);

//显示联系人信息
void ShowContact(const Contact* pc);

//删除联系人
void DeleteContact(Contact *pc);

//查找
void SearchContact(Contact* pc);

//修改
void ModfityContact(Contact* pc);

//排序
void SortContact(Contact* pc);

//清空
void EmptyContact(Contact* pc);

动态版本

可以按需分配,更有效的利用存储空间

  • test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
//添加联系人信息
//删除指定联系人信息
//查找指定联系人信息
//修改指定联系人信息
//显示所有联系人信息
//清空所有联系人
//以名字排序所有联系人

enum Option
{
	EXIT,
	ADD,
	DELETE,
	SEARCH,
	MODIFY,
	SORT,
	SHOW,
	EMPTY,
};

void menu()
{
	printf("******************************\n");
	printf("****  1.Add     2.Del     ****\n");
	printf("****  3.search  4.modify  ****\n");
	printf("****  5.sort    6.show    ****\n");
	printf("****  7.empty   0.exit    ****\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	Contact con = { 0 };
	InitContact(&con);//初始化通讯录
	do 
	{
		menu();
		printf("请选择:->");
		scanf_s("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DELETE:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModfityContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case EMPTY:
			DestroyContact(&con);
			break;
		case EXIT:
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择:\n");
			break;
		}
	} while (input);
	return 0;
}
  • contact.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->date = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
	if (pc->date == NULL)
	{
		printf("%s\n", strerror(errno));
		return;
	}
	pc->capacity = DEFAULT_SZ;
}

void CheckCapacity(Contact* pc)
{
	if (pc->capacity == pc->sz)
	{
		PeoInfo* ptr =(PeoInfo*) realloc(pc->date, (pc->capacity * 2)*sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->date = ptr;
			pc->capacity *= 2;
			printf("增容成功!\n");
		}
	}
}
void Scanf_(Contact* pc)
{
	printf("请输入联系人名字:");
	scanf("%s", pc->date[pc->sz].name);

	printf("请输入联系人性别:");
	scanf("%s", pc->date[pc->sz].sex);

	printf("请输入联系人年龄:");
	scanf("%d", &(pc->date[pc->sz].age));

	printf("请输入联系人电话号码:");
	scanf("%s", pc->date[pc->sz].tele);

	printf("请输入联系人地址:");
	scanf("%s", pc->date[pc->sz].addr);
}

void AddContact(Contact* pc)
{
	assert(pc);
	CheckCapacity(pc); //插入前检查扩容情况
	Scanf_(pc);
	pc->sz++;
	printf("添加成功!\n");
}


void ShowContact(const Contact* pc)
{
	assert(pc);
	printf("%-15s\t%-5s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0;i < pc->sz; i++)
	{
		printf("%-15s\t%-5s\t%-5d\t%-15s\t%-20s\n", 
			pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	for (int i = 0;i < pc->sz; i++)
	{
		if (strcmp(pc->date[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}


void DeleteContact(Contact* pc) 
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,删除失败!\n");
		return;
	}
	printf("请输入删除联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在!\n");
		return;
	}
	else
	{
		for (int i = 0;i < pc->sz - 1;i++)
		{
			pc->date[i] = pc->date[i + 1];
		}
		pc->sz--;
		printf("删除成功!\n");
	}
}


void SearchContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,查找失败!\n");
		return;
	}
	printf("请输入查找联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在,查找失败!\n");
		return;
	}
	else
	{
		printf("查找成功信息如下:\n");
		printf("%-15s\t%-5s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-15s\t%-5s\t%-5d\t%-15s\t%-20s\n",
			pc->date[Index].name, pc->date[Index].sex,
			pc->date[Index].age, pc->date[Index].tele, pc->date[Index].addr);
	}
}


void ModfityContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,修改失败!\n");
		return;
	}
	printf("请输入修改联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在,查找失败!\n");
		return;
	}
	else{
		Scanf_(pc);
		printf("修改成功!\n");
	}
}
int cmp_byname(const void* e1, const void* e2)
{
	return strcmp(((Contact*)e1)->date->name, ((Contact*)e2)->date->name);
}

void SortContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,排序失败!\n");
		return;
	}
	qsort(pc->date, pc->sz, sizeof(pc->date[0]), cmp_byname);
	printf("排序成功!\n");
}

void DestroyContact(Contact* pc)
{
	free(pc->date);
	pc->date = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

  • contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12


#define DEFAULT_SZ 10


typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo *date;
	int sz;//有效元素的个数
	int capacity;//容量
}Contact;

//初始化通讯录
void InitContact(Contact *pc);

//增加联系人信息
void AddContact(Contact* pc);

//显示联系人信息
void ShowContact( Contact* pc);

//删除联系人
void DeleteContact(Contact *pc);

//查找
void SearchContact(Contact* pc);

//修改
void ModfityContact(Contact* pc);

//排序
void SortContact(Contact* pc);

//清空
void DestroyContact(Contact* pc);



文件版本

可以把信息记录到文件中

  • test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
//添加联系人信息
//删除指定联系人信息
//查找指定联系人信息
//修改指定联系人信息
//显示所有联系人信息
//清空所有联系人
//以名字排序所有联系人

enum Option
{
	EXIT,
	ADD,
	DELETE,
	SEARCH,
	MODIFY,
	SORT,
	SHOW,
	EMPTY,
};

void menu()
{
	printf("******************************\n");
	printf("****  1.Add     2.Del     ****\n");
	printf("****  3.search  4.modify  ****\n");
	printf("****  5.sort    6.show    ****\n");
	printf("****  7.empty   0.exit    ****\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	Contact con = { 0 };
	InitContact(&con);//初始化通讯录
	do 
	{
		menu();
		printf("请选择:->");
		scanf_s("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DELETE:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModfityContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case EMPTY:
			DestroyContact(&con);
			break;
		case EXIT:
			SavaContact(&con);
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择:\n");
			break;
		}
	} while (input);
	return 0;
}
  • contact.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->date = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
	if (pc->date == NULL)
	{
		printf("%s\n", strerror(errno));
		return;
	}
	pc->capacity = DEFAULT_SZ;

	LoadContact(pc);//初始化数据到内存中
}

void LoadContact(Contact* pc)
{
	FILE* pf = fopen("Contact.txt", "wd");
	if (NULL == pf)
	{
		printf("加载信息失败!");
		printf("%s\n", strerrorr(errno));
		return;
	}
	PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(PeoInfo), 1, pf))
	{
		CheckCapacity(pc);
		pc->date[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pf);
	pf == NULL;
}

void CheckCapacity(Contact* pc)
{
	if (pc->capacity == pc->sz)
	{
		PeoInfo* ptr =(PeoInfo*) realloc(pc->date, (pc->capacity * 2)*sizeof(PeoInfo));
		if (ptr != NULL)
		{
			pc->date = ptr;
			pc->capacity *= 2;
			printf("增容成功!\n");
		}
	}
}
void Scanf_(Contact* pc)
{
	printf("请输入联系人名字:");
	scanf("%s", pc->date[pc->sz].name);

	printf("请输入联系人性别:");
	scanf("%s", pc->date[pc->sz].sex);

	printf("请输入联系人年龄:");
	scanf("%d", &(pc->date[pc->sz].age));

	printf("请输入联系人电话号码:");
	scanf("%s", pc->date[pc->sz].tele);

	printf("请输入联系人地址:");
	scanf("%s", pc->date[pc->sz].addr);
}

void AddContact(Contact* pc)
{
	assert(pc);
	CheckCapacity(pc); //插入前检查扩容情况
	Scanf_(pc);
	pc->sz++;
	printf("添加成功!\n");
}


void ShowContact(const Contact* pc)
{
	assert(pc);
	printf("%-15s\t%-5s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0;i < pc->sz; i++)
	{
		printf("%-15s\t%-5s\t%-5d\t%-15s\t%-20s\n", 
			pc->date[i].name, pc->date[i].sex, pc->date[i].age, pc->date[i].tele, pc->date[i].addr);
	}
}
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	for (int i = 0;i < pc->sz; i++)
	{
		if (strcmp(pc->date[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}


void DeleteContact(Contact* pc) 
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,删除失败!\n");
		return;
	}
	printf("请输入删除联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在!\n");
		return;
	}
	else
	{
		for (int i = 0;i < pc->sz - 1;i++)
		{
			pc->date[i] = pc->date[i + 1];
		}
		pc->sz--;
		printf("删除成功!\n");
	}
}


void SearchContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,查找失败!\n");
		return;
	}
	printf("请输入查找联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在,查找失败!\n");
		return;
	}
	else
	{
		printf("查找成功信息如下:\n");
		printf("%-15s\t%-5s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-15s\t%-5s\t%-5d\t%-15s\t%-20s\n",
			pc->date[Index].name, pc->date[Index].sex,
			pc->date[Index].age, pc->date[Index].tele, pc->date[Index].addr);
	}
}


void ModfityContact(Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,修改失败!\n");
		return;
	}
	printf("请输入修改联系人名字:");
	scanf("%s", name);
	int Index = FindByName(pc, name);
	if (Index == -1)
	{
		printf("联系人不存在,查找失败!\n");
		return;
	}
	else{
		Scanf_(pc);
		printf("修改成功!\n");
	}
}
int cmp_byname(const void* e1, const void* e2)
{
	return strcmp(((Contact*)e1)->date->name, ((Contact*)e2)->date->name);
}

void SortContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,排序失败!\n");
		return;
	}
	qsort(pc->date, pc->sz, sizeof(pc->date[0]), cmp_byname);
	printf("排序成功!\n");
}

void DestroyContact(Contact* pc)
{
	free(pc->date);
	pc->date = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}


void SavaContact(Contact* pc)
{
	FILE* pf = fopen("Contact.txt", "wd");
	//打开文件
	if (NULL == pf)
	{
		printf("保存信息失败!");
		printf("%s\n", strerrorr(errno));
		return;
	}
	//保存文件
	for (int i = 0;i < pc->sz;i++)
	{
		fwrite(pc->date + i, sizeof(PeoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf == NULL;
}
  • contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12


#define DEFAULT_SZ 10


typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo *date;
	int sz;//有效元素的个数
	int capacity;//容量
}Contact;

//初始化通讯录
void InitContact(Contact *pc);

//增加联系人信息
void AddContact(Contact* pc);

//显示联系人信息
void ShowContact( Contact* pc);

//删除联系人
void DeleteContact(Contact *pc);

//查找
void SearchContact(Contact* pc);

//修改
void ModfityContact(Contact* pc);

//排序
void SortContact(Contact* pc);

//清空
void DestroyContact(Contact* pc);


//保存
void SavaContact(Contact* pc);



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zzt.opkk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值