【C】通讯录管理系统详解(内含完整代码下载+简单实现+动态内存实现+文件操作)


前言

通讯录作为一个基本小项目,可以有效的巩固好对于动态内存和指针的使用。


一、实现效果预览(简单版本)

        1.基本介绍

  • 存放1000个联系人       
  1. 增加联系人
  2. 删除联系人
  3. 查找联系人
  4. 修改联系人
  5. 依据名字排序联系人
  6. 展示通讯录
  7. 清除通讯录 

        2.预览

二、实现逻辑(简单版本)

  1. 首先在主函数中使用switch决定用户选择
  2. 增加:判断通讯录有没有满,依次输入用户信息
  3. 删除:判断通讯录是否还有联系人,寻找需要删除联系人的位置,删除或者没有找到联系人
  4. 查找:判断所查联系人是否存在,存在则打印联系人
  5. 修改:判断所查联系人是否存在,存在直接修改信息
  6. 排序:依次遍历,依次按字符交换
  7. 展示:依次打印联系人
  8. 清除:初始化通讯录

三、完整代码解析(简单版本)

contact.h

#define _CRT_SECURE_NO_WARNINGS 1

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

#define Population_MAX 1000//通讯录联系人数量
#define Name_MAX 20//名字
#define Sex_MAX 5//性别
#define telephone_number_MAX 12//电话
#define Address_number_MAX 30//地址

//枚举封装
enum Option
{
    EXIT,//默认从0开始
    ADD,//1
    DEL,//2
    SEARCH,//3
    MODIFY,//4
    SORT,//5
    SHOW,//6
    CLEAR//7
};

//每个人基本信息
typedef  struct Human_nformation
{
    char name[Name_MAX];
    int age;
    char sex[Sex_MAX];
    char address[Address_number_MAX];
    char telephone_number[telephone_number_MAX];
}Human_nformation;

//通讯录结构体
typedef struct Contact
{
    Human_nformation data[Population_MAX];//存放1000个人的数据
    int sz;//通讯录中有效信息的个数
}Contact;

//菜单
void menu(void);
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人到通讯录
void AddContact(Contact* pc);
//显示通讯录数据
void ShowContact(Contact* pc);
//删除通信录数据
void DeleteContact(Contact* pc);
//查找指定成员
void SearchContact(Contact* pc);
//修改指定的成员
void ModifyContact(Contact* pc);
//排序成员信息
void SortContact(Contact* pc);
//清空成员信息
void ClearContact(Contact* pc);

contact.c

#include "contact.h"

//菜单
void menu(void)
{
    printf("***************************************\n");
    printf("********  1.add      2.del    *********\n");
    printf("********  3.search   4.modify *********\n");
    printf("********  5.sort     6.show   *********\n");
    printf("********  7.clear    0.exit   *********\n");
    printf("***************************************\n");
}

//初始化结构体
void InitContact(Contact* pc)
{
    assert(pc != NULL);
    pc->sz = 0;//有效联系人初始化
    memset(pc->data, 0, sizeof(pc->data));//初始化data:起始地址,元素的值,元素个数
}

//增加联系人
void AddContact(Contact* pc)
{
    assert(pc != NULL);
    if (pc->sz == Population_MAX)
    {
        printf("通讯录满了\n");
        return;
    }
    printf("输入联系人名字:");
    scanf("%s", pc->data[pc->sz].name);
    printf("输入联系人年龄:");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("输入联系人性别:");
    scanf("%s", pc->data[pc->sz].sex);
    printf("输入联系人地址:");
    scanf("%s", pc->data[pc->sz].address);
    printf("输入联系人电话:");
    scanf("%s", pc->data[pc->sz].telephone_number);
    //记录完后,有效联系人加一
    pc->sz++;
    printf("记录完成\n");
}

//打印通讯录
void ShowContact(Contact* pc)
{
    assert(pc != NULL);
    printf("%-15s\t%-2s\t%-3s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
    for (int i = 0; i < pc->sz; i++)
    {
        printf("%-15s\t%-2d\t%-3s\t%-20s\t%-12s\n", 
                pc->data[i].name,
                pc->data[i].age, 
                pc->data[i].sex, 
                pc->data[i].address, 
                pc->data[i].telephone_number);
    }
}

//在通讯录中依次查找匹配
int FindContact(Contact* pc, char name[])
{
    for (int i = 0; i < pc->sz; i++)
    {
        //匹配
        if (strcmp(pc->data[i].name, name) == 0)
        {
            //找到了就返回对应下标
            return i;
        }
    }
    return -1;
}

//删除联系人
void DeleteContact(Contact* pc)
{
    char name[Population_MAX] = { 0 };
    if (pc->sz == 0)
    {
        printf("通讯录为空\n");
    }
    printf("输入需要删除的联系人:");
    scanf("%s",name);
    int pos = FindContact(pc, name);
    if (pos == -1)
    {
        printf("要删除联系人不在\n");
    }
    else
    {
        //删除联系人只需将此联系人覆盖
        for (int j = pos; j < pc->sz - 1; j++)
        {
            pc->data[j] = pc->data[j + 1];
        }
        pc->sz--;
        printf("删除指定联系人成功\n");
    }
}

//查找联系人
void SearchContact(Contact* pc)
{
    char name[Population_MAX] = { 0 };
    printf("请输入要查找人的姓名:");
    scanf("%s", name);
    //判断该成员是否存在
    int pos = FindContact(pc, name);
    if (pos == -1)//不存在
    {
        printf("要查找人的信息不存在\n");
    }
    else//存在,打印该成员的信息
    {
        printf("%-15s\t%-2s\t%-3s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
        printf("%-15s\t%-2d\t%-3s\t%-20s\t%-12s\n",
            pc->data[pos].name,
            pc->data[pos].age,
            pc->data[pos].sex,
            pc->data[pos].address,
            pc->data[pos].telephone_number);
    }
}

//修改联系人
void ModifyContact(Contact* pc)
{
    char name[Population_MAX] = { 0 };
    printf("请输入要修改人的名字:");
    scanf("%s", name);
    //判断该成员是否存在
    int pos = FindContact(pc, name);
    if (pos == -1)//不存在
    {
        printf("要修改人的信息不存在\n");
    }
    else//存在,通过访问结构体成员直接修改信息
    {
        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)).address);

        printf("请输入电话:");
        scanf("%s", (*((pc->data) + pos)).telephone_number);

        printf("修改成功\n");
    }
}
//比较两个元素
int My_Compare_Struct(void* e1, void* e2)
{
    return strcmp(((Human_nformation*)e1)->name, ((Human_nformation*)e2)->name);
}

//交换两个元素
void My_Swap(void* e1, void* e2, int width)
{
    while (width)
    {
        char tmp = *(char*)e1;
        *(char*)e1 = *(char*)e2;
        *(char*)e2 = tmp;
        (char*)e1 = (char*)e1 + 1;
        (char*)e2 = (char*)e2 + 1;
        width--;
    }
}
//排序
void My_Qsort(void* pc, int sz, int width, int(*cmp)(void*, void*))
{
    for (int i = 0; i < sz - 1; i++)
    {
        for (int j = 0; j < sz - 1; j++)
        {
            //判断是否需要交换两个元素
            if (cmp((char*)pc + (j * width), (char*)pc + ((j + 1) * width)) > 0)
            {
                My_Swap((char*)pc + (j * width), (char*)pc + ((j + 1) * width), width);
            }
        }
    }
}

//排序
void SortContact(Contact* pc)
{
    My_Qsort(pc->data, pc->sz, sizeof(pc->data[0]), My_Compare_Struct);
    printf("排序完成\n");
}

//清理通讯录
void ClearContact(Contact* pc)
{
    void InitContact(Contact * pc);
    printf("清空完成\n");
}


main.c

#define _CRT_SECURE_NO_WARNINGS 1

/************************************************************  

FileName: 通讯录

Author:JugKing

Date:2022.1.23

***********************************************************/

//通讯录
//存放1000个人的信息
//人的信息:名字,年龄,电话,住址,性别
//增加联系人
//删除联系人
//查找联系人
//修改联系人
//清空联系人
//排序(名字,年龄)

#include "contact.h"


int main ()
{
	int input = 0;
	//简单初始化
	Contact con = { 0 };
	//函数初始化
	InitContact(&con);
	do 
	{
		menu();
		printf("请选择:");
		scanf("%d",&input);
		switch(input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case CLEAR:
			ClearContact(&con);
			break;
		case EXIT:
			printf("通讯录结束\n");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);
	
	return 0;
}

一、实现效果预览(动态内存版本)

 1.基本介绍

  • 存放1000个联系人       
  1. 增加联系人
  2. 删除联系人
  3. 查找联系人
  4. 修改联系人
  5. 依据名字排序联系人
  6. 展示通讯录
  7. 清除通讯录 

        2.预览

二、实现逻辑(动态内存版本)

  1. 首先在主函数中使用switch决定用户选择
  2. 增加:判断通讯录有没有满,如果满了就增加容量,再增加联系人
  3. 删除:判断通讯录是否还有联系人,寻找需要删除联系人的位置,删除或者没有找到联系人
  4. 查找:判断所查联系人是否存在,存在则打印联系人
  5. 修改:判断所查联系人是否存在,存在直接修改信息
  6. 排序:依次遍历,依次按字符交换
  7. 展示:依次打印联系人
  8. 清除:清楚对应的内存和指针

三、完整代码解析(动态内存版本)

contact.h

#define _CRT_SECURE_NO_WARNINGS 1

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

#define Population_MAX 1000//最大容量
#define Name_MAX 20//名字
#define Sex_MAX 5//性别
#define telephone_number_MAX 12//电话
#define Address_number_MAX 30//地址
#define Default_MAX 3//默认值

//封装
enum Option
{
    EXIT,//默认从0开始
    ADD,//1
    DEL,//2
    SEARCH,//3
    MODIFY,//4
    SORT,//5
    SHOW,//6
    CLEAR//7
};

//每个人基本信息
typedef  struct Human_nformation
{
    char name[Name_MAX];
    int age;
    char sex[Sex_MAX];
    char address[Address_number_MAX];
    char telephone_number[telephone_number_MAX];
}Human_nformation;

//通讯录结构体
typedef struct Contact
{
    //Human_nformation data[Population_MAX];//存放1000个人的数据
    Human_nformation* data;//存放数据
    int sz;//通讯录中有效信息的个数
    int Capacity;//记录当前通讯录的最大容量
}Contact;

//菜单
void menu(void);
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人到通讯录
void AddContact(Contact* pc);
//显示通讯录数据
void ShowContact(Contact* pc);
//删除通信录数据
void DeleteContact(Contact* pc);
//查找指定成员
void SearchContact(Contact* pc);
//修改指定的成员
void ModifyContact(Contact* pc);
//排序成员信息
void SortContact(Contact* pc);
//清空成员信息
void ClearContact(Contact* pc);

contact.c

#include "contact.h"

//菜单
void menu(void)
{
    printf("***************************************\n");
    printf("********  1.add      2.del    *********\n");
    printf("********  3.search   4.modify *********\n");
    printf("********  5.sort     6.show   *********\n");
    printf("********  7.clear    0.exit   *********\n");
    printf("***************************************\n");
}

//初始化
void InitContact(Contact* pc)
{
    assert(pc != NULL);
    pc->sz = 0;
    //memset(pc->data, 0, sizeof(pc->data));
    //开辟一个默认值大小的空间
    Human_nformation* tmp = (Human_nformation*)malloc(Default_MAX*sizeof(Human_nformation));
    //不是空指针的话在赋值给data
    if (tmp != NULL)
    {
        pc->data = tmp;
    }
    //否则打印错误
    else
    {
        printf("InitContact:%s",strerror(errno));
        return;
    }
    //默认值也依次赋给容量
    pc->Capacity = Default_MAX;
}

//增加联系人
void AddContact(Contact* pc)
{
    assert(pc != NULL);
    if (pc->sz == pc->Capacity)//满了
    {
        //调整空间大小
        Human_nformation* tmp = (Human_nformation*)realloc(pc->data, sizeof(Human_nformation)*(pc->Capacity + 2));
        //没问题则幅值
        if (tmp != NULL)
        {
            pc->data = tmp;
            pc->Capacity += 2;
            printf("增容成功\n");
        }
        //有错误则打印错误
        else
        {
            printf("%s", strerror(errno));
            return;
        }
    }
    printf("输入联系人名字:");
    scanf("%s", pc->data[pc->sz].name);
    printf("输入联系人年龄:");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("输入联系人性别:");
    scanf("%s", pc->data[pc->sz].sex);
    printf("输入联系人地址:");
    scanf("%s", pc->data[pc->sz].address);
    printf("输入联系人电话:");
    scanf("%s", pc->data[pc->sz].telephone_number);

    pc->sz++;
    printf("记录完成\n");
}

//打印通讯录
void ShowContact(Contact* pc)
{
    assert(pc != NULL);
    printf("%-15s\t%-2s\t%-3s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
    for (int i = 0; i < pc->sz; i++)
    {
        printf("%-15s\t%-2d\t%-3s\t%-20s\t%-12s\n", 
                pc->data[i].name,
                pc->data[i].age, 
                pc->data[i].sex, 
                pc->data[i].address, 
                pc->data[i].telephone_number);
    }
}

//在通讯录中匹配
int FindContact(Contact* pc, char name[])
{
    for (int i = 0; i < pc->sz; i++)
    {
        if (strcmp(pc->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

//删除联系人
void DeleteContact(Contact* pc)
{
    char name[Population_MAX] = { 0 };
    if (pc->sz == 0)
    {
        printf("通讯录为空\n");
    }
    printf("输入需要删除的联系人:");
    scanf("%s",name);
    int pos = FindContact(pc, name);
    if (pos == -1)
    {
        printf("要删除联系人不在\n");
    }
    else
    {
        for (int j = pos; j < pc->sz - 1; j++)
        {
            pc->data[j] = pc->data[j + 1];
        }
        pc->sz--;
        printf("删除指定联系人成功\n");
    }
}

//查找联系人
void SearchContact(Contact* pc)
{
    char name[Population_MAX] = { 0 };
    printf("请输入要查找人的姓名:");
    scanf("%s", name);
    //判断该成员是否存在
    int pos = FindContact(pc, name);
    if (pos == -1)//不存在
    {
        printf("要查找人的信息不存在\n");
    }
    else//存在,打印该成员的信息
    {
        printf("%-15s\t%-2s\t%-3s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
        printf("%-15s\t%-2d\t%-3s\t%-20s\t%-12s\n",
            pc->data[pos].name,
            pc->data[pos].age,
            pc->data[pos].sex,
            pc->data[pos].address,
            pc->data[pos].telephone_number);
    }
}

//修改联系人
void ModifyContact(Contact* pc)
{
    char name[Population_MAX] = { 0 };
    printf("请输入要修改人的名字:");
    scanf("%s", name);
    //判断该成员是否存在
    int pos = FindContact(pc, name);
    if (pos == -1)//不存在
    {
        printf("要修改人的信息不存在\n");
    }
    else//存在,通过访问结构体成员直接修改信息
    {
        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)).address);

        printf("请输入电话:");
        scanf("%s", (*((pc->data) + pos)).telephone_number);

        printf("修改成功\n");
    }
}

//比较两个结构体
int My_Compare_Struct(void* e1, void* e2)
{
    return strcmp(((Human_nformation*)e1)->name, ((Human_nformation*)e2)->name);
}

//交换两个结构体
void My_Swap(void* e1, void* e2, int width)
{
    while (width)
    {
        char tmp = *(char*)e1;
        *(char*)e1 = *(char*)e2;
        *(char*)e2 = tmp;
        (char*)e1 = (char*)e1 + 1;
        (char*)e2 = (char*)e2 + 1;
        width--;
    }
}

//排序
void My_Qsort(void* pc, int sz, int width, int(*cmp)(void*, void*))
{
    for (int i = 0; i < sz - 1; i++)
    {
        for (int j = 0; j < sz - 1; j++)
        {
            //判断是否需要交换两个元素
            if (cmp((char*)pc + (j * width), (char*)pc + ((j + 1) * width)) > 0)
            {
                My_Swap((char*)pc + (j * width), (char*)pc + ((j + 1) * width), width);
            }
        }
    }
}

void SortContact(Contact* pc)
{
    My_Qsort(pc->data, pc->sz, sizeof(pc->data[0]), My_Compare_Struct);
    printf("排序完成\n");
}

//清空通讯录
void ClearContact(Contact* pc)
{
    //void InitContact(Contact * pc);
    assert(pc != NULL);
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->Capacity = 0;
    printf("清空完成\n");
}


main.c

#define _CRT_SECURE_NO_WARNINGS 1

/************************************************************  

FileName: 通讯录

Author:JugKing

Date:2022.1.23

***********************************************************/

//通讯录
//存放1000个人的信息
//人的信息:名字,年龄,电话,住址,性别
//增加联系人
//删除联系人
//查找联系人
//修改联系人
//清空联系人
//排序(名字,年龄)

#include "contact.h"


int main ()
{
	int input = 0;
	Contact con = { 0 };
	InitContact(&con);
	do 
	{
		menu();
		printf("请选择:");
		scanf("%d",&input);
		switch(input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case CLEAR:
			ClearContact(&con);
			break;
		case EXIT:
			printf("通讯录结束\n");
			break;
		default:
			printf("输入错误,重新输入\n");
			break;
		}
	} while (input);
	
	return 0;
}

四、通讯录(文件操作版本)

改动说明:

        保存信息

//保存通讯录的信息
void Save_Contact(struct contact* ps)
{
	FILE* pfWrite = fopen("contact.dat", "wb");
	if (pfWrite == NULL)
	{
		printf("Save_Contact::%s", strerror(errno));
		return;
	}
	//将通讯录中的数据到文件中
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		fwrite(&(ps->data[i]), sizeof(struct PeoInfo), 1, pfWrite);
	}
	printf("保存成功!\n");
	//关闭文件
	fclose(pfWrite);
	pfWrite = NULL;
}

        销毁通讯录

//销毁通讯录
void Destory_Contact(struct contact* ps)
{
	free(ps->data);
	ps->data = NULL;
}

         初始化

//加载文件中的信息到通讯录中
void Load_Contact(struct contact* ps)
{
	
	FILE* pfRead = fopen("contact.dat", "rb");
	if (pfRead== NULL)
	{
		printf("Load_Contact::%s", strerror(errno));
		return;
	}
	//读取文件存放到通讯录中
	struct PeoInfo tmp = { 0 };
	while (fread(&tmp,sizeof(tmp),1,pfRead))
	{
		CheckCapacity(ps);
		ps->data[ps->size] = tmp;
		ps->size++;
		printf("读取成功!\n");
	}
	
	//关闭文件
	fclose(pfRead);
	pfRead = NULL;
}
 
//初始化通讯录中的信息
void Init_Contact(struct contact* ps)
{
	ps->data = (struct PeoInfo*)malloc(sizeof(struct PeoInfo) * 3);
	if (ps->data == NULL)
	{
		return;
	}
	ps->size = 0;//设置通讯录最初只有0个元素
	ps->capacity = DEFAULT_SZ;
	//把文件中已经存放的信息加载到通讯录中
	Load_Contact(ps);
}

main.c

#include"contact.h"
enum Option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SHOW,//5
	CLEAR,//6
	SORT,//7
	SAVE
};
void menu()
{
	printf("************************************\n");
	printf("****  1.add         2.del       ****\n");
	printf("****  3.search      4.modify    ****\n");
	printf("****  5.show        6.clear     ****\n");
	printf("****  7.sort        8.save      ****\n");
	printf("*********     0.exit      **********\n");
	printf("************************************\n");
}
//测试函数的功能
int main()
{
	//创建通讯录
	struct contact con;//con就是通讯录,里面包含:data指针和size,capacity
	//初始化通讯录
	Init_Contact(&con);
	int input = 0;
	int size = 0;//记录当前有多少人
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			//增加
			Add_Contacter(&con);
			break;
		case DEL:
			//删除
			Del_Contacter(&con);
			break;
		case SEARCH:
			//查找
			Find_Contacter(&con);
			break;
		case MODIFY:
			//修改
			Mod_Contacter(&con);
			break;
		case SHOW:
			//打印
			Print_Contacter(&con);
			break;
		case CLEAR:
			//清空
			Clear_Contacter(&con);
			break;
		case SORT:
			//排序
			Sort_Contacter(&con);
			break;
		case EXIT:
		    //退出并销毁通讯录
			Save_Contact(&con);
			Destory_Contact(&con);
			printf("退出通讯录!\n");
			break;
		case 8:
			//保存通讯录
			Save_Contact(&con);
			break;
		default:
			printf("选择错误,请重新输入!\n");
		}
	} while (input);
	return 0;
}

contact.h

#pragma once
#define MAX_NAME 20
#define MAX_PHONE 12
#define MAX_SEX 5
#define MAX_ADDRESS 30
#define _CRT_SECURE_NO_WARNINGS 1
#define DEFAULT_SZ 3
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
struct PeoInfo
{
	char name[MAX_NAME];
	char phone[MAX_PHONE];
	char sex[MAX_SEX];
	char address[MAX_ADDRESS];
	int age;
};
struct contact
{
	struct PeoInfo* data;
	int size;//记录当前已经有的元素个数
	int capacity;//记录当前通讯录的最大容量
};
//声明函数
//初始化通讯录的函数
void Init_Contact(struct contact* ps);
//增加一个信息到通讯录
void Add_Contacter(struct contact* ps);
//删除指定的联系人
void Del_Contacter(struct contact* ps);
//查找指定人的信息
void Find_Contacter(const struct contact* ps);
//修改指定人的信息
void Mod_Contacter(struct contact* ps);
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps);
//对通讯录中的联系人进行排序
void Sort_Contacter(struct contact* ps);
//清空通讯录中的信息
void Clear_Contacter(struct contact* ps);
//销毁通讯录
void Destory_Contact(struct contact*ps);
//保存通讯录的信息
void Save_Contact(struct contact* ps);
//加载文件中的信息到通讯录中
void Load_Contact(struct contact* ps);

contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
//实现函数的功能
static int Find_byName(const struct contact* ps, char name[MAX_NAME])
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (0 == strcmp(ps->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}
void CheckCapacity(struct contact*);
//加载文件中的信息到通讯录中
void Load_Contact(struct contact* ps)
{
	
	FILE* pfRead = fopen("contact.dat", "rb");
	if (pfRead== NULL)
	{
		printf("Load_Contact::%s", strerror(errno));
		return;
	}
	//读取文件存放到通讯录中
	struct PeoInfo tmp = { 0 };
	while (fread(&tmp,sizeof(tmp),1,pfRead))
	{
		CheckCapacity(ps);
		ps->data[ps->size] = tmp;
		ps->size++;
		printf("读取成功!\n");
	}
	
	//关闭文件
	fclose(pfRead);
	pfRead = NULL;
}
 
//初始化通讯录中的信息
void Init_Contact(struct contact* ps)
{
	ps->data = (struct PeoInfo*)malloc(sizeof(struct PeoInfo) * 3);
	if (ps->data == NULL)
	{
		return;
	}
	ps->size = 0;//设置通讯录最初只有0个元素
	ps->capacity = DEFAULT_SZ;
	//把文件中已经存放的信息加载到通讯录中
	Load_Contact(ps);
}
void CheckCapacity(struct contact* ps)
{
	if (ps->size == ps->capacity)
	{
		//增容
		struct PeoInfo* ptr= realloc(ps->data, (ps->capacity + 2)*sizeof(struct PeoInfo));
		if (ptr != NULL)
		{
			ps->data = ptr;
			ps->capacity += 2;
			printf("增容成功!\n");
		}
		else
		{
			printf("增容失败!\n");
		}
	}
}
//添加通讯录中的信息
void Add_Contacter(struct contact* ps)
{
	//检测当前通讯录的容量
	//1、如果满了,就增加空间
	//2、如果不满,啥事都不干
	CheckCapacity(ps);
	//增加数据
	printf("请输入名字:");
	scanf("%s", &ps->data[ps->size].name);
	printf("请输入年龄:");
	scanf("%d", &ps->data[ps->size].age);
	printf("请输入性别:");
	scanf("%s", &ps->data[ps->size].sex);
	printf("请输入电话:");
	scanf("%s", &ps->data[ps->size].phone);
	printf("请输入地址:");
	scanf("%s", &ps->data[ps->size].address);
 
	ps->size++;
	printf("添加成功!\n");
}
//删除通讯录中的信息
void Del_Contacter(struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要删除的联系人的姓名:");
	scanf("%s", name);
	//查找要删除的人所在的位置
	//找到了返回名字所在元素的下标,没找到就返回-1
	int pos = Find_byName(ps,name);
	if (pos==-1)//删除的人不存在
	{
		printf("要删除的人不存在!\n");
	}
	else//删除
	{
		int j = 0;
		for (j = pos; j < ps->size-1; j++)
		{
			ps->data[j] = ps->data[j + 1];
		}
		ps->size--;
		printf("删除成功!\n");
	}
}
//查找通讯录中的信息
void Find_Contacter(const struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要查找的联系人的姓名:");
	scanf("%s", name);
	int pos = Find_byName(ps, name);
	if (pos==-1)//查找的人不存在
	{
		printf("要查找的人不存在!\n");
	}
	else
	{
		printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[pos].name,
			ps->data[pos].age,
			ps->data[pos].sex,
			ps->data[pos].phone,
			ps->data[pos].address);
	}
}
//修改通讯录中的信息
void Mod_Contacter(struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要修改的联系人的姓名:");
	scanf("%s", name);
	int pos = Find_byName(ps, name);
	if (pos==-1)//修改的人不存在
	{
		printf("要修改的人不存在!\n");
	}
	else
	{
		printf("请输入名字:");
		scanf("%s", &ps->data[pos].name);
		printf("请输入年龄:");
		scanf("%d", &ps->data[pos].age);
		printf("请输入性别:");
		scanf("%s", &ps->data[pos].sex);
		printf("请输入电话:");
		scanf("%s", &ps->data[pos].phone);
		printf("请输入地址:");
		scanf("%s", &ps->data[pos].address);
		printf("修改成功!\n");
	}
}
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps)
{
	if (ps->size == 0)
	{
		printf("通讯录为空!\n");
	}
	else
	{
		//标题
		printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n",  "姓名", "年龄", "性别", "电话", "地址");
		int i = 0;
		while (i < ps->size)
		{
			//数据
			printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name, 
				ps->data[i].age, 
				ps->data[i].sex, 
				ps->data[i].phone, 
				ps->data[i].address);
			i++;
		}
	}
}
//对通讯录中的信息进行排序
//排序函数
//1.按照姓名进行排序
int Conpare_ByName(const void *e1,const void *e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
	return ((struct PeoInfo*)e1)->age-((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->address, ((struct PeoInfo*)e2)->address);
}
void Sort_Contacter(struct contact* ps)
{
	printf("请选择你想排序的方式:\n");
	printf("1.姓名\n2.年龄\n3.住址\n");
	int input = 0;
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		qsort(ps->data,ps->size,sizeof(ps->data[0]),Conpare_ByName);
		printf("排序成功\n");
		break;
	case 2:
		qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAge);
		printf("排序成功\n");
		break;
	case 3:
		qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAddress);
		printf("排序成功\n");
		break;
	}
}
//清空通讯中的信息
void Clear_Contacter(struct contact* ps)
{
	memset(ps->data, 0, sizeof(ps->data));
	ps->size = 0;
	printf("清空成功!\n");
}
//销毁通讯录
void Destory_Contact(struct contact* ps)
{
	free(ps->data);
	ps->data = NULL;
}
//保存通讯录的信息
void Save_Contact(struct contact* ps)
{
	FILE* pfWrite = fopen("contact.dat", "wb");
	if (pfWrite == NULL)
	{
		printf("Save_Contact::%s", strerror(errno));
		return;
	}
	//将通讯录中的数据到文件中
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		fwrite(&(ps->data[i]), sizeof(struct PeoInfo), 1, pfWrite);
	}
	printf("保存成功!\n");
	//关闭文件
	fclose(pfWrite);
	pfWrite = NULL;
}

五、项目下载

通讯录1.0:Txet: 记录代码 - Gitee.com

通讯录2.0:Txet: 记录代码 - Gitee.com

通讯录3.0:Txet: 记录代码 - Gitee.com


总结

        说实话自己做一个项目自己还是很有成就感的,虽然过程很累但是自己还是觉得自己是值得的,最近找回了以前那种能一直努力奋斗都不会感到累,完全进入到心流的状态了,我自己是很满足的,好不容易找到这种感觉的话那就好好保持吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

penguin_bark

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

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

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

打赏作者

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

抵扣说明:

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

余额充值