通 讯 录

test.c              测试通讯录逻辑的模块

contact.h        头文件的包含,类型定义,函数声明

contact. c       通讯录相关函数的实现

版本1 - 静态版本

静态版本,顾名思义,就是能储存的联系人的数量是静态的,固定的,比如通讯录的大小为1000,那么就只能储存1000位联系人的信息,不能多存。

思路:

 memset函数   http://t.csdn.cn/zZTHJ 

完整代码: 

排序功能使用qsort函数,此篇文章不再实现。

test.c

#include"contact.h"

//通讯录
//1.通讯录中能够存放1000个人的信息
//  每个人的信息:
//  名字+年龄+性别+电话+地址
// 2.增加人的信息
// 3.删除指定人的信息
// 4.查找指定人的信息
// 5.修改指定人的信息
// 6.排序通讯录的信息
 

void meau()
{
	printf("****************************************\n");
	printf("*********** 1.add      2.del ***********\n");
	printf("*********** 3.serrch   4.modify ********\n");
	printf("*********** 5.sort     6.print  ********\n");
	printf("**************  0.exit  ****************\n");
	printf("****************************************\n");
}

enum Option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SORT,//5
	PRINT//6
};

int main()
{
	int input = 0;//创建通讯录
	struct Contact con;//通讯录
	//初始化通讯录
	InitContact(&con);	
	do
	{
		meau();
		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 SORT:
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h

#pragma once
#include <stdio.h>
#include<string.h>

//类型的定义
#define MAXE_NAME 20
#define MAX_SEX 10
#define MAX_DELE 12
#define MAX_ADDREES 30
#define MAX  1000

struct PeoInfo
{
	char name[MAXE_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_DELE];
	char address[MAX_ADDREES];
}PeoInfo;

//通讯录
struct Contact
{
	struct PeoInfo data[MAX];//存放添加进来的人的信息
	int sz;//记录的是当前通讯录中已有元素的个数
};

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

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

//打印联系人信息
void PrintContact(const struct Contact* pc);//只打印,不修改,加上const,可以防止不小心修改,更安全

//查找某个人是否存在
int FindByname(struct Contact* pc, char name[]);

//删除联系人信息
void DelContact(struct Contact* pc);

//查找某个人的信息
void SearchContact(struct Contact* pc);

//修改联系人信息
void ModifyContact(struct Contact* pc);

contact.c

#include"contact.h"

//初始化通讯录
void InitContact(struct Contact* pc)
{
	pc->sz = 0;
	memset(pc->data, 0,sizeof(pc->data));
	//数组名表示首元素地址,pc->data也表示首元素地址
}

//增加联系人
void AddContact(struct Contact* pc)
{
	//判断通讯录是否有空间
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
			return;//结束函数
	}
	//增加一个人的信息
	printf("请输入名字:->\n");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:->\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄:->\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入电话:->\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址:->\n");
	scanf("%s", pc->data[pc->sz].address);
	pc->sz++;
	printf("添加成功\n");
}

//打印联系人
void PrintContact(const struct Contact* pc)
{
	int i = 0;
	//打印标题
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n","名字","性别","年龄","电话","地址");
	//打印信息
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n", pc->data[i].name,
													pc->data[i].sex,
													pc->data[i].age,
													pc->data[i].tele,
													pc->data[i].address);
	}
}

//查找某个人是否存在
static int FindByname(struct Contact* pc, char name[])//static修饰函数时,函数只能在自己源文件中看到,别人看不到,可以保护函数
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
			return i;//找到就返回它的下标
	}
	return -1;//找不到
}


//删除某个人的信息
void DelContact(struct Contact* pc)
{
	//通讯录不为空才能删除
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需删除\n");
		return;
	}
	char name[MAXE_NAME];//要声明一下,否则后面报错
	printf("请输入要删除人的名字:->\n");
	scanf("%s", name);
	//查找某个人是否存在
	int pos=FindByname(pc,name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//如果存在,删除
	int i = 0;
	for (i = pos; i < pc->sz-1; i++)
	{
		pc->data[i] = pc->data[i+1];
	}
	pc->sz--;
	printf("删除成功\n");
}
//查找某个人的信息
void SearchContact(struct Contact* pc)
{
	char name[MAXE_NAME];//={0};
	printf("请输入要查找人的名字:->\n");
	scanf("%s", name);
	int pos = FindByname(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n", pc->data[pos].name,
													pc->data[pos].sex,
													pc->data[pos].age,
													pc->data[pos].tele,
													pc->data[pos].address);
	}
}

//修改联系人信息
void ModifyContact(struct Contact* pc)
{
	char name[MAXE_NAME];//={0};
	printf("请输入要修改人的名字:->\n");
	scanf("%s", name);
	int pos = FindByname(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	else
	{
		//修改一个人的信息
		printf("请输入名字:->\n");
		scanf("%s", pc->data[pos].name);
		printf("请输入性别:->\n");
		scanf("%s", pc->data[pos].sex);
		printf("请输入年龄:->\n");
		scanf("%d", &(pc->data[pos].age));
		printf("请输入电话:->\n");
		scanf("%s", pc->data[pos].tele);
		printf("请输入地址:->\n");
		scanf("%s", pc->data[pos].address);
		//pc->sz++;修改不会影响元素个数,不要动
		printf("修改成功\n");
	}
}

版本2 - 动态版本

动态版本,就是通讯录满了,会自动增容,(在一定的总空间大小下,不能无限增加),以储存新的联系人。

动态版本的优点:刚开始我们可能为了节省内存,将容量设置为50人,但是认识的人越来越多,联系人可能超过50人,动态版本的通讯录就会自动增加。动态版本不仅在一定程度上节省了空间,而且通讯录满了,还能自动增容,比静态通讯录更灵活。

思路:

静态通讯录转变为动态通讯录,基本框架是不变的。
主要发生改变的是,涉及动态内存的:

  1. 通讯录类型定义、创建,初始化
  2. 增加联系人函数的定义
  3. 如何退出通讯录(动态内存开辟,必然涉及空间回收,否则有内存泄漏的风险)

完整代码:

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"

//动态版本
//1.通讯录初始化后,能存放3个人的信息
//2.当空间存放满时,增加2个信息,再满的时候,再增加两个信息
//3+2+2+2+2+2……

void meau()
{
	printf("****************************************\n");
	printf("*********** 1.add      2.del ***********\n");
	printf("*********** 3.serrch   4.modify ********\n");
	printf("*********** 5.sort     6.print  ********\n");
	printf("**************  0.exit  ****************\n");
	printf("****************************************\n");
}

enum Option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SORT,//5
	PRINT//6
};


int main()
{
	int input = 0;//创建通讯录
	struct Contact con;//通讯录
	//初始化通讯录
	//给data在堆区上申请一块连续的空间,sz=0,capacity=0
	InitContact(&con);
	do
	{
		meau();
		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 SORT:
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT://销毁通讯录
			//printf("退出通讯录\n");
			DestoryContact(&con);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h

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


//类型的定义
#define MAXE_NAME 20
#define MAX_SEX 10
#define MAX_DELE 12
#define MAX_ADDREES 30
#define MAX  1000

#define DEFAULT_SZ 3
#define INC_ADDR 2

struct PeoInfo
{
	char name[MAXE_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_DELE];
	char address[MAX_ADDREES];
}PeoInfo;

//通讯录
struct Contact
{
	struct PeoInfo *data;//存放添加进来的人的信息
	int sz;//记录当前通讯录中已有元素的个数
	int capacity;//记录当前通讯录的最大容量
};

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

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

//打印联系人信息
void PrintContact(const struct Contact* pc);//只打印,不修改,加上const,可以防止不小心修改,更安全

//查找某个人是否存在
int FindByname(struct Contact* pc, char name[]);

//删除联系人信息
void DelContact(struct Contact* pc);

//查找某个人的信息
void SearchContact(struct Contact* pc);

//修改联系人信息
void ModifyContact(struct Contact* pc);

//销毁通讯录
void DestoryContact(struct Contact* pc);

contact.c

#include"contact.h"

//初始化通讯录
void InitContact(struct Contact* pc)
{
	pc->data = (struct PeoInfo*)malloc(DEFAULT_SZ * sizeof(struct PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->capacity = MAX_ADDREES;
}


//增加联系人
void AddContact(struct Contact* pc)
{
	//考虑增容
	if (pc->sz == pc->capacity)
	{
		struct PeoInfo*ptr =(struct PeoInfo*) realloc(pc->data, (pc->capacity+ INC_ADDR)*sizeof(struct PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_ADDR;//容量增加
			printf("增容成功\n");
		}
		else
		{
			perror("AddContact");
			printf("增加联系人失败\n");
			return;
		}
	}
	//增加一个人的信息
	printf("请输入名字:->\n");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:->\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄:->\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入电话:->\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址:->\n");
	scanf("%s", pc->data[pc->sz].address);
	pc->sz++;
	printf("添加成功\n");
}

//打印联系人
void PrintContact(const struct Contact* pc)
{
	int i = 0;
	//打印标题
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n","名字","性别","年龄","电话","地址");
	//打印信息
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n", pc->data[i].name,
													pc->data[i].sex,
													pc->data[i].age,
													pc->data[i].tele,
													pc->data[i].address);
	}
}

//查找某个人是否存在
static int FindByname(struct Contact* pc, char name[])//static修饰函数时,函数只能在自己源文件中看到,别人看不到,可以保护函数
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
			return i;//找到就返回它的下标
	}
	return -1;//找不到
}

//删除某个人的信息
void DelContact(struct Contact* pc)
{
	//通讯录不为空才能删除
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需删除\n");
		return;
	}
	char name[MAXE_NAME];//要声明一下,否则后面报错
	printf("请输入要删除人的名字:->\n");
	scanf("%s", name);
	//查找某个人是否存在
	int pos=FindByname(pc,name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//如果存在,删除
	int i = 0;
	for (i = pos; i < pc->sz-1; i++)
	{
		pc->data[i] = pc->data[i+1];
	}
	pc->sz--;
	printf("删除成功\n");
}

//查找某个人的信息
void SearchContact(struct Contact* pc)
{
	char name[MAXE_NAME];//={0};
	printf("请输入要查找人的名字:->\n");
	scanf("%s", name);
	int pos = FindByname(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n", pc->data[pos].name,
													pc->data[pos].sex,
													pc->data[pos].age,
													pc->data[pos].tele,
													pc->data[pos].address);
	}
}

//修改联系人信息
void ModifyContact(struct Contact* pc)
{
	char name[MAXE_NAME];//={0};
	printf("请输入要修改人的名字:->\n");
	scanf("%s", name);
	int pos = FindByname(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	else
	{
		//修改一个人的信息
		printf("请输入名字:->\n");
		scanf("%s", pc->data[pos].name);
		printf("请输入性别:->\n");
		scanf("%s", pc->data[pos].sex);
		printf("请输入年龄:->\n");
		scanf("%d", &(pc->data[pos].age));
		printf("请输入电话:->\n");
		scanf("%s", pc->data[pos].tele);
		printf("请输入地址:->\n");
		scanf("%s", pc->data[pos].address);
		//pc->sz++;修改不会影响元素个数,不要动
		printf("修改成功\n");
	}
}

//销毁通讯录
void DestoryContact(struct Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

开辟动态内存的函数:http://t.csdn.cn/9CTKN

版本3 - 文件版本

动态版本虽然满足了灵活添加联系人的要求,但是我们每次保存完信息,下次再打开程序,上次保存的通讯人信息就没有了,那么如何解决这个这个问题呢?

(建议学完文件后再来阅读这一版本通讯录。)

可以通过文件解决。

思路:

退出通讯录之前,把联系人信息保存到一个文件中(此处文件名为:contact.dat)

打开通讯录后,在初始化函数这一阶段,读取上次保存在文件中的联系人信息,输入到程序中的通讯录中。

这样就满足了通讯录的保存功能。

完整代码:

test.c​​​​​​​

#include"contact.h"

// 版本3
//当通讯录退出时,把信息写到文件
// 当通讯录初始化时,加载文件的信息到通讯录中
// 
//

void meau()
{
	printf("****************************************\n");
	printf("*********** 1.add      2.del ***********\n");
	printf("*********** 3.serrch   4.modify ********\n");
	printf("*********** 5.sort     6.print  ********\n");
	printf("**************  0.exit  ****************\n");
	printf("****************************************\n");
}

enum Option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SORT,//5
	PRINT//6
};


int main()
{
	int input = 0;//创建通讯录
	struct Contact con;//通讯录
	//初始化通讯录
	//给data在堆区上申请一块连续的空间,sz=0,capacity=0
	InitContact(&con);
	do
	{
		meau();
		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 SORT:
			break;
		case PRINT:
			PrintContact(&con);
			break;
		case EXIT:
			//保存信息到文件
			SaveContact(&con);
			//销毁通讯录			
			DestoryContact(&con);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h​​​​​​​

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


//类型的定义
#define MAXE_NAME 20
#define MAX_SEX 10
#define MAX_DELE 12
#define MAX_ADDREES 30
#define MAX  1000

#define DEFAULT_SZ 3
#define INC_ADDR 2

struct PeoInfo
{
	char name[MAXE_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_DELE];
	char address[MAX_ADDREES];
}PeoInfo;

//通讯录
struct Contact
{
	struct PeoInfo *data;//存放添加进来的人的信息
	int sz;//记录当前通讯录中已有元素的个数
	int capacity;//记录当前通讯录的最大容量
};

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

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

//打印联系人信息
void PrintContact(const struct Contact* pc);//只打印,不修改,加上const,可以防止不小心修改,更安全

//查找某个人是否存在
int FindByname(struct Contact* pc, char name[]);

//删除联系人信息
void DelContact(struct Contact* pc);

//查找某个人的信息
void SearchContact(struct Contact* pc);

//修改联系人信息
void ModifyContact(struct Contact* pc);

//销毁通讯录
void DestoryContact(struct Contact* pc);

//保存信息到文件
void SaveContact(struct Contact* pc);

//加载文件
void LoadContact(struct Contact* pc);

//考虑增容
void CheckCapacity(struct Contact* pc);

contact.c

#include"contact.h"

//加载文件
void LoadContact(struct Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.dat", "r");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	//读文件
	struct PeoInfo tmp = { 0 };
	while (fread(&tmp, sizeof(struct PeoInfo), 1, pf))
	{
		//是否需要增容
		CheckCapacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
		
	//关闭文件
	fclose(pf);
	pf = NULL;
}

//初始化通讯录
void InitContact(struct Contact* pc)
{
	pc->data = (struct PeoInfo*)malloc(DEFAULT_SZ * sizeof(struct PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->capacity = MAX_ADDREES;

	//加载文件
	LoadContact(pc);
}

//考虑增容
void CheckCapacity(struct Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		struct PeoInfo* ptr = (struct PeoInfo*)realloc(pc->data, (pc->capacity + INC_ADDR) * sizeof(struct PeoInfo));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->capacity += INC_ADDR;//容量增加
			printf("增容成功\n");
		}
		else
		{
			perror("AddContact");
			printf("增加联系人失败\n");
			return;
		}
	}
}

//增加联系人
void AddContact(struct Contact* pc)
{
	//考虑增容
	CheckCapacity(pc);
	//增加一个人的信息
	printf("请输入名字:->\n");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:->\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄:->\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入电话:->\n");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入地址:->\n");
	scanf("%s", pc->data[pc->sz].address);
	pc->sz++;
	printf("添加成功\n");
}

//打印联系人
void PrintContact(const struct Contact* pc)
{
	int i = 0;
	//打印标题
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n","名字","性别","年龄","电话","地址");
	//打印信息
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n", pc->data[i].name,
													pc->data[i].sex,
													pc->data[i].age,
													pc->data[i].tele,
													pc->data[i].address);
	}
}

//查找某个人是否存在
static int FindByname(struct Contact* pc, char name[])//static修饰函数时,函数只能在自己源文件中看到,别人看不到,可以保护函数
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
			return i;//找到就返回它的下标
	}
	return -1;//找不到
}

//删除某个人的信息
void DelContact(struct Contact* pc)
{
	//通讯录不为空才能删除
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需删除\n");
		return;
	}
	char name[MAXE_NAME];//要声明一下,否则后面报错
	printf("请输入要删除人的名字:->\n");
	scanf("%s", name);
	//查找某个人是否存在
	int pos=FindByname(pc,name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//如果存在,删除
	int i = 0;
	for (i = pos; i < pc->sz-1; i++)
	{
		pc->data[i] = pc->data[i+1];
	}
	pc->sz--;
	printf("删除成功\n");
}

//查找某个人的信息
void SearchContact(struct Contact* pc)
{
	char name[MAXE_NAME];//={0};
	printf("请输入要查找人的名字:->\n");
	scanf("%s", name);
	int pos = FindByname(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");
		printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n", pc->data[pos].name,
													pc->data[pos].sex,
													pc->data[pos].age,
													pc->data[pos].tele,
													pc->data[pos].address);
	}
}

//修改联系人信息
void ModifyContact(struct Contact* pc)
{
	char name[MAXE_NAME];//={0};
	printf("请输入要修改人的名字:->\n");
	scanf("%s", name);
	int pos = FindByname(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	else
	{
		//修改一个人的信息
		printf("请输入名字:->\n");
		scanf("%s", pc->data[pos].name);
		printf("请输入性别:->\n");
		scanf("%s", pc->data[pos].sex);
		printf("请输入年龄:->\n");
		scanf("%d", &(pc->data[pos].age));
		printf("请输入电话:->\n");
		scanf("%s", pc->data[pos].tele);
		printf("请输入地址:->\n");
		scanf("%s", pc->data[pos].address);
		//pc->sz++;修改不会影响元素个数,不要动
		printf("修改成功\n");
	}
}

//销毁通讯录
void DestoryContact(struct Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

//保存信息到文件
void SaveContact(struct Contact* pc)
{   
	//打开文件
	FILE* pf = fopen("contact.dat", "w");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(struct PeoInfo), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
好的,这个程序看起来比较简单,需要用到C语言的文件操作和基本的数据结构。以下是一个简单的实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LEN 50 #define MAX_WORKPLACE_LEN 100 #define MAX_EMAIL_LEN 100 #define MAX_PHONE_NUM_LEN 20 typedef struct { int student_id; char name[MAX_NAME_LEN]; char gender; char workplace[MAX_WORKPLACE_LEN]; char phone_num[MAX_PHONE_NUM_LEN]; char email[MAX_EMAIL_LEN]; } Contact; void print_menu(); void insert_contact(FILE *fp); void modify_contact(FILE *fp); void delete_contact(FILE *fp); void display_contacts(FILE *fp); void count_contacts(FILE *fp); void search_contacts(FILE *fp); int main() { FILE *fp; int choice; fp = fopen("contacts.dat", "rb+"); if (fp == NULL) { fp = fopen("contacts.dat", "wb+"); if (fp == NULL) { printf("Failed to open file!\n"); return 1; } } do { print_menu(); scanf("%d", &choice); switch (choice) { case 1: insert_contact(fp); break; case 2: modify_contact(fp); break; case 3: delete_contact(fp); break; case 4: display_contacts(fp); break; case 5: count_contacts(fp); break; case 6: search_contacts(fp); break; case 7: printf("Thanks for using the program!\n"); break; default: printf("Invalid choice!\n"); break; } } while (choice != 7); fclose(fp); return 0; } void print_menu() { printf("--------------------\n"); printf("1. Insert contact\n"); printf("2. Modify contact\n"); printf("3. Delete contact\n"); printf("4. Display contacts\n"); printf("5. Count contacts\n"); printf("6. Search contacts\n"); printf("7. Exit\n"); printf("--------------------\n"); } void insert_contact(FILE *fp) { Contact c; printf("Enter student ID: "); scanf("%d", &c.student_id); printf("Enter name: "); scanf("%s", c.name); printf("Enter gender (M/F): "); scanf(" %c", &c.gender); printf("Enter workplace: "); scanf("%s", c.workplace); printf("Enter phone number: "); scanf("%s", c.phone_num); printf("Enter email: "); scanf("%s", c.email); fseek(fp, 0, SEEK_END); fwrite(&c, sizeof(Contact), 1, fp); printf("Contact added!\n"); } void modify_contact(FILE *fp) { int id; Contact c; int found = 0; printf("Enter student ID to modify: "); scanf("%d", &id); rewind(fp); while (fread(&c, sizeof(Contact), 1, fp) == 1) { if (c.student_id == id) { printf("Enter new name (or press Enter to keep the old one): "); scanf("\n%[^\n]", c.name); printf("Enter new gender (M/F or press Enter to keep the old one): "); scanf(" %c", &c.gender); printf("Enter new workplace (or press Enter to keep the old one): "); scanf("\n%[^\n]", c.workplace); printf("Enter new phone number (or press Enter to keep the old one): "); scanf("%s", c.phone_num); printf("Enter new email (or press Enter to keep the old one): "); scanf("%s", c.email); fseek(fp, -sizeof(Contact), SEEK_CUR); fwrite(&c, sizeof(Contact), 1, fp); found = 1; break; } } if (!found) { printf("Contact not found!\n"); } else { printf("Contact modified!\n"); } } void delete_contact(FILE *fp) { int id; Contact c; int found = 0; printf("Enter student ID to delete: "); scanf("%d", &id); rewind(fp); FILE *temp_fp = fopen("temp.dat", "wb"); while (fread(&c, sizeof(Contact), 1, fp) == 1) { if (c.student_id != id) { fwrite(&c, sizeof(Contact), 1, temp_fp); } else { found = 1; } } fclose(temp_fp); if (!found) { printf("Contact not found!\n"); remove("temp.dat"); } else { printf("Contact deleted!\n"); remove("contacts.dat"); rename("temp.dat", "contacts.dat"); } } void display_contacts(FILE *fp) { Contact c; rewind(fp); printf("%-10s %-20s %-10s %-30s %-20s %-30s\n", "ID", "Name", "Gender", "Workplace", "Phone Number", "Email"); while (fread(&c, sizeof(Contact), 1, fp) == 1) { printf("%-10d %-20s %-10c %-30s %-20s %-30s\n", c.student_id, c.name, c.gender, c.workplace, c.phone_num, c.email); } } void count_contacts(FILE *fp) { Contact c; rewind(fp); int male_count = 0, female_count = 0, total_count = 0; while (fread(&c, sizeof(Contact), 1, fp) == 1) { if (c.gender == 'M') { male_count++; } else if (c.gender == 'F') { female_count++; } total_count++; } printf("Total contacts: %d\n", total_count); printf("Male contacts: %d\n", male_count); printf("Female contacts: %d\n", female_count); } void search_contacts(FILE *fp) { int choice; Contact c; int found = 0; printf("Search by:\n"); printf("1. Student ID\n"); printf("2. Name\n"); printf("3. Phone Number\n"); scanf("%d", &choice); switch (choice) { case 1: printf("Enter student ID to search: "); scanf("%d", &c.student_id); break; case 2: printf("Enter name to search: "); scanf("%s", c.name); break; case 3: printf("Enter phone number to search: "); scanf("%s", c.phone_num); break; default: printf("Invalid choice!\n"); return; } rewind(fp); printf("%-10s %-20s %-10s %-30s %-20s %-30s\n", "ID", "Name", "Gender", "Workplace", "Phone Number", "Email"); while (fread(&c, sizeof(Contact), 1, fp) == 1) { if ((choice == 1 && c.student_id == c.student_id) || (choice == 2 && strcmp(c.name, c.name) == 0) || (choice == 3 && strcmp(c.phone_num, c.phone_num) == 0)) { printf("%-10d %-20s %-10c %-30s %-20s %-30s\n", c.student_id, c.name, c.gender, c.workplace, c.phone_num, c.email); found = 1; } } if (!found) { printf("No contacts found!\n"); } } ``` 程序使用了一个结构体 `Contact` 来保存每位联系人的信息,同时使用了文件来保存所有联系人的信息。在主函数中,打开文件并根据用户的选择执行不同的功能。以下是每个功能的具体实现: 1. `insert_contact`:让用户输入新联系人的信息,并将其添加到文件中。 2. `modify_contact`:让用户输入要修改的联系人的学号,然后查找文件中是否有该联系人。如果找到,让用户输入新信息,并将其更新到文件中。 3. `delete_contact`:让用户输入要删除的联系人的学号,然后查找文件中是否有该联系人。如果找到,将其从文件中删除。 4. `display_contacts`:在屏幕上显示所有联系人的信息。 5. `count_contacts`:统计所有联系人的数量以及男女联系人的数量,并在屏幕上显示。 6. `search_contacts`:让用户选择按照学号、姓名或电话号码查询联系人,然后在文件中查找并在屏幕上显示符合条件的联系人。 程序使用了文件操作函数 `fopen`、`fread`、`fwrite`、`fseek`、`fclose`、`remove` 和 `rename`,以及字符串操作函数 `scanf` 和 `printf`。其中,`scanf` 和 `printf` 的格式化字符串需要根据不同的数据类型进行调整,否则可能会导致输入输出错误。程序还使用了一些基本的流程控制语句和数据结构,需要熟悉这些基本知识才能理解和编写这个程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值