模拟实现动态通讯录

核心

  • 多了一个每次增加容量的大小的宏
  • 在添加前/删除后/读入后, 需要检查容量, 是否需要增加 / 减少容量
  • 动态开辟 / 内存释放 malloc() / free()

实现

  • m.h 文件
#ifndef __contact_h__
#define __contact_h__
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

//初始容量大小
#define MAX_NUM 1
//每次增加容量的大小
#define INCREASE_NUM 1

#define MAX_NAME 24
#define MAX_SEX 10
#define MAX_TEL 20
#define MAX_ADDRESS 20

//个人信息
typedef struct People{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char age;
	char tel[MAX_TEL];
	char address[MAX_ADDRESS];
} Peo;
//保存多个个人信息
typedef struct Contact{
	int count;//已存数目
	Peo *con;//**与静态不同,这里需要改成指针**
	int max_size;//**当前最大容量**
} Con;
//选项
enum Choice{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MOD,
	SHOW,
	EMPTY,
	NAMESORT,
	SAVE,
	LOAD
};

//函数声明
void initContact(Con* pcon);//初始化
void add(Con* pcon);//添加
void del(Con* pcon);//删除
void search(Con* pcon);//查找
void mod(Con* pcon);//修改
void show(Con* pcon);//展示
void empty(Con* pcon);//清空
void namesort(Con* pcon);//按名字排序
void save(Con* pcon);//保存到文件中
void load(Con* pcon);//从文件中载入


#endif __contact_h__
  • main.c
#include "m.h"
//初始化(动态开辟)
void initContact(Con* pcon){
	//malloc开辟
	pcon->con = (Peo*)malloc(MAX_NUM * sizeof(Peo));
	pcon->count = 0;
	pcon->max_size = MAX_NUM;
	memset(pcon->con, 0, MAX_NUM * sizeof(Peo));
	printf("初始化成功!\n");
}
//检查容量/增容函数
static void CheckIncrease(Con* pcon){
	//需要增加容量的情况
	if (pcon->count == pcon->max_size){
		printf("通讯录已满!\n");
		//realloc 重新开辟
		pcon->con = (Peo*)realloc(pcon->con, (pcon->max_size + INCREASE_NUM) * sizeof(Peo));
		//把 max_size 变成增加容量后的大小
		pcon->max_size = pcon->max_size + INCREASE_NUM;
		if (pcon != NULL){
			printf("增加容量成功!\n");
		}
	}
	//需要减少容量的情况
	if (pcon->count < pcon->max_size - INCREASE_NUM){
		//减容
		pcon->con = (Peo*)realloc(pcon->con, (pcon->max_size - INCREASE_NUM) * sizeof(Peo));
		printf("减容成功\n");
	}
}
//添加联系人(是否需要增加容量)
void add(Con* pcon){
	//count 代表已经存放的联系人的个数
	//max_size 代表当前最大容量
	if (pcon->con == NULL){//在清空操作的时候,把 pcon->con = NULL;了
		initContact(pcon);//检查容量
	}
	CheckIncrease(pcon);
	printf("请输入姓名 :");
	scanf("%s", pcon->con[pcon->count].name);
	printf("请输入性别 :");
	scanf("%s", pcon->con[pcon->count].sex);
	printf("请输入年龄 :");
	scanf("%d", &(pcon->con[pcon->count].age));
	printf("请输入电话 :");
	scanf("%s", pcon->con[pcon->count].tel);
	printf("请输入地址 :");
	scanf("%s", pcon->con[pcon->count].address);
	pcon->count++;
	printf("添加成功!\n");
}
//删除(删除之后,总容量是否需要减容)
void del(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入要删除联系人的姓名 :");
	scanf("%s", name);
	int i = 0;
	for (i = 0; i < pcon->count; i++){
		if (strcmp(name, pcon->con[i].name) == 0){
			int j = 0;
			for (j = i; j < pcon->count - 1; j++){//把联系人依次往前挪
				pcon->con[j] = pcon->con[j + 1];
			}
			pcon->count--;
			printf("找到联系人,并删除成功!\n");
			CheckIncrease(pcon);//检查容量
			return;
		}
	}
	if (i == pcon->count){
		printf("未找到该联系人,请重新输入!\n");
	}
}
//查找
void search(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入要查找联系人的姓名 :");
	scanf("%s", name);
	int i = 0;
	for (i = 0; i < pcon->count; i++){
		if (strcmp(name, pcon->con[i].name) == 0){
			printf("找到联系人!\n");
			printf(" %d ", i + 1);
			printf("%-5s %-3s %-3d %-15s %-15s\n", pcon->con[i].name, pcon->con[i].sex
				, pcon->con[i].age, pcon->con[i].tel, pcon->con[i].address);
			break;
		}
	}
	if (i == pcon->count){
		printf("未找到该联系人,请重新输入!\n");
	}
}
//修改
void mod(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入要修改联系人的姓名 :");
	scanf("%s", name);
	int i = 0;
	for (i = 0; i < pcon->count; i++){
		if (strcmp(name, pcon->con[i].name) == 0){
			printf("找到联系人!\n");
			printf("请输入姓名 :");
			scanf("%s", pcon->con[i].name);
			printf("请输入性别 :");
			scanf("%s", pcon->con[i].sex);
			printf("请输入年龄 :");
			scanf("%d", &(pcon->con[i].age));
			printf("请输入电话 :");
			scanf("%s", pcon->con[i].tel);
			printf("请输入地址 :");
			scanf("%s", pcon->con[i].address);
			printf("修改成功!\n");
			break;
		}
	}
	if (i == pcon->count){
		printf("未找到该联系人,请重新输入!\n");
	}
}
//展示
void show(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	printf("当前最大容量   : %d\n", pcon->max_size);
	printf("当前已使用容量 : %d\n", pcon->count);
	int i = 0;
	printf("   %-5s %-3s %-3s %-15s %-15s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (i = 0; i < pcon->count; i++){
		printf(" %d ", i + 1);
		printf("%-5s %-3s %-3d %-15s %-15s\n", pcon->con[i].name, pcon->con[i].sex
			, pcon->con[i].age, pcon->con[i].tel, pcon->con[i].address);
	}
}
//清空(free)
void empty(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	pcon->count = 0;
	pcon->max_size = MAX_NUM;
	printf("清空成功");
}
//按名字排序
void namesort(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	int i = 0;
	int j = 0;
	for (i = 0; i < pcon->count - 1; i++){
		for (j = 0; j < pcon->count - i - 1; j++){
			if (strcmp(pcon->con[i].name, pcon->con[i + 1].name) > 0){
				Peo tmp = pcon->con[i];
				pcon->con[i] = pcon->con[i + 1];
				pcon->con[i + 1] = tmp;
			}
		}
	}
	printf("排序成功!\n");
	show(pcon);
}
//保存到文件里
void save(Con* pcon){
	if (pcon->count == 0){
		printf("通讯录已空!\n");
		return;
	}
	FILE* fp = fopen("contact.text", "w");
	assert(fp);
	int i = 0;
	for (i = 0; i < pcon->count; i++){
		fprintf(fp, "%-5s %-3s %-3d %-15s %-15s\n", pcon->con[i].name, pcon->con[i].sex
			, pcon->con[i].age, pcon->con[i].tel, pcon->con[i].address);
	}
	printf("写入成功!\n");
	fclose(fp);
	fp = NULL;
}
//从文件里读入(每次读入之后都要需要检查容量)
void load(Con* pcon){
	FILE* fp = fopen("contact.text", "r");
	if (fp == NULL){
		printf("没有文件\n");
	}
	int i = 0;
	//fgetc() != EOF 或 fgets() != NULL检测是否到达文件末尾
	//feof()判断是否到达文件末尾
	for (i = pcon->count; !feof(fp); i++){
		//格式化输入,中间的数字代表一次输入几个字符
		fscanf(fp, "%5s %3s %3d %15s %15s", pcon->con[i].name, pcon->con[i].sex
			, &(pcon->con[i].age), pcon->con[i].tel, pcon->con[i].address);
		pcon->count++;
		CheckIncrease(pcon);//检查容量函数
	}
	pcon->count--;
	printf("读入成功!\n");
	show(pcon);
	fclose(fp);
	fp = NULL;
}

  • test.c (相比静态通讯录,没有变化)
#include "m.h"

void menu(){
	printf("********************************************************\n");
	printf("*****1. add  2. del  3. search  4. mod******************\n");
	printf("*****5. show 6. empty 7. nameSort 8. save 9 .load*******\n");
	printf("********************************************************\n");
}

int main() {
	menu();
	Con con;
	initContact(&con);//初始化
	assert(&con != NULL);
	while (1){
		int choice = 0;
		printf("请输入操作: ");
		scanf("%d", &choice);
		switch (choice){
		case ADD:
			add(&con);
			break;
		case DEL:
			del(&con);
			break;
		case SEARCH:
			search(&con);
			break;
		case MOD:
			mod(&con);
			break;
		case SHOW:
			show(&con);
			break;
		case EMPTY:
			empty(&con);
			break;
		case NAMESORT:
			namesort(&con);
			break;
		case SAVE:
			save(&con);
			break;
		case LOAD:
			load(&con);
			break;
		case EXIT:
			printf("退出成功!\n");
			break;
		default:
			break;
		}
	}
	return 0;
}
发布了60 篇原创文章 · 获赞 5 · 访问量 2643

猜你喜欢

转载自blog.csdn.net/qq_44905386/article/details/100079514