通讯录的实现(I/O文件版本)

MailList.h文件

#ifndef __MAILLIST__H__
#define __MAILLIST__H__

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <assert.h>

#define M 10 //通讯录默认大小,即默认存储10个人
#define N 5  //扩大/缩小一次通讯录容量的大小

struct Person//个人信息
{
    char Name[20];
    char Sex[4];
    int Age;
    int PhoneNumber;
    char Address[40];
};

struct MailList//通讯录(数组)
{
    int EP;   //已有人数:Existing Population
    int MP;   //当前最大存储人数
    struct Person *person;
}ML;//(通讯录)结构体指针,用于接收动态分配的空间地址


//////////////////////////////////////////////////////
void InitMailList();//初始化函数
void Expand();//扩大通讯录容量
void Reduce();//缩小通讯录容量
void Release();//释放动态申请的空间
/////////////////////////////////////////////////////
void AddPerson(struct Person *person);//添加联系人
void ShowPerson(struct Person *person);//显示联系人
void InitPerson(struct Person *person);//初始化通讯录
int FindPerson(struct Person *person);//查找联系人,返回其下标
void SearchPerson(struct Person *person);//查找联系人,打印其信息
void DeletePerson(struct Person *person);//删除联系人
void ModifyPerson(struct Person *person);//修改联系人
void EmptyPerson(struct Person *person);//情况通讯录
void SortPerson(struct Person *person);//排序联系人
/////////////////////////////////////////////////////
void Save();//保存(写入)文件
void Load();//加载(读入)文件


#endif//__MAILLIST__H__

MailList.c文件

#define _CRT_SECURE_NO_WARNINGS -1

#include "MailList.h"

void InitMailList()//初始化函数
{
    ML.EP = 0;
    ML.MP = M;
    ML.person = (struct Person *)malloc(sizeof(struct Person)*M);//动态分配默认大小的空间,即10个struct Person类的大小


    if (ML.person == NULL)//动态申请空间失败
    {
        perror("malloc");
        return;
    }

    memset(ML.person, 0, sizeof(struct Person)*M);//将通讯录全部初始化为0
}

void Expand()//扩大通讯录容量
{
    struct Person * tmp = (struct Person *)realloc(ML.person, sizeof(struct Person)*(ML.MP + N));
    //重新定义一个指针接收realloc分配的空间地址,而不是直接用原空间指针接收
    //是为了防止出现申请空间失败返回NULL导致原空间指针被置NULL

    if (tmp == NULL)//动态申请空间失败
    {
        perror("malloc");
        return;
    }

    ML.person = tmp;
    ML.MP += N;//当前最大容量增加N
}

void Reduce()//缩小通讯录容量
{
    if (ML.EP > (ML.MP - N) || 0 >= (ML.MP - N))//如果缩小后的空间不足以存储当前人数或缩小后的空间小于等于0
    {
        printf("通讯录容量不足以缩小!\n");
        return;
    }
    struct Person * tmp = (struct Person *)realloc(ML.person, sizeof(struct Person)*(ML.MP - N));

    if (tmp == NULL)//动态申请空间失败
    {
        perror("malloc");
        return;
    }

    ML.person = tmp;
    ML.MP -= N;//当前最大容量减少N
}

void ShowPerson(struct Person *person)//显示联系人信息
{
    assert(person);
    if (0 == ML.EP)
    {
        printf("通讯录为空!\n");
        return;
    }
    int i = 0;
    for (i = 0; i < ML.EP; i++)
    {
        printf("%s  ", person[i].Name);
        printf("%s  ", person[i].Sex);
        printf("%d  ", person[i].Age);
        printf("%d  ", person[i].PhoneNumber);
        printf("%s  ", person[i].Address);
        printf("\n");
    }
}

void Release()//释放动态申请的空间
{
    if (ML.person!=NULL)
    {
        free(ML.person);
    }
    ML.person = NULL;
}


void AddPerson(struct Person *person)//添加联系人信息
{
    assert(person);

    if (ML.EP == ML.MP)
    {
        printf("通讯录已满!\n");
        return;
    }

    printf("输入名字:>\n");
    scanf("%s", &person[ML.EP].Name);

    printf("输入性别:>\n");
    scanf("%s", &person[ML.EP].Sex);

    printf("输入年龄:>\n");
    scanf("%d", &person[ML.EP].Age);

    printf("输入手机号:>\n");
    scanf("%d", &person[ML.EP].PhoneNumber);

    printf("输入地址:>\n");
    scanf("%s", &person[ML.EP].Address);

    ML.EP++;   //已添加人数加一
}

int FindPerson(struct Person *person)//按名字查找联系人信息,返回其下标
{
    assert(person);
    int i = 0;

    printf("请输入姓名:>");
    char name[10] = { 0 };
    scanf("%s", name);

    for (i = 0; i < ML.EP; i++)
    {
        if (0 == strcmp(person[i].Name, name))
        {
            return i;
        }
    }
    printf("不存在该联系人!\n");
    return -1;
}

void SearchPerson(struct Person *person)//按名字查找联系人信息,打印其信息
{
    assert(person);
    int i = FindPerson(person);
    if (i >= 0)
    {
        printf("%s  ", person[i].Name);
        printf("%s  ", person[i].Sex);
        printf("%d  ", person[i].Age);
        printf("%d  ", person[i].PhoneNumber);
        printf("%s  ", person[i].Address);
        printf("\n");
    }
}

void DeletePerson(struct Person *person)//删除指定姓名的联系人信息
{
    assert(person);
    int i = 0;
    int ret = 0;

    ret = FindPerson(person);

    if (ret == ML.EP - 1)//恰好删除最后一个
    {
        ML.EP--;
    }

    else if (ret >= 0 && ret<ML.EP)
    {

        person[ret] = person[ML.EP - 1];
        ML.EP--;
    }
}

void ModifyPerson(struct Person *person)//修改联系人信息
{
    assert(person);
    int ret = 0;
    ret = FindPerson(person);

    if (ret >= 0)
    {
        printf("输入名字:>\n");
        scanf("%s", &person[ret].Name);

        printf("输入性别:>\n");
        scanf("%s", &person[ret].Sex);

        printf("输入年龄:>\n");
        scanf("%d", &person[ret].Age);

        printf("输入手机号:>\n");
        scanf("%d", &person[ret].PhoneNumber);

        printf("输入地址:>\n");
        scanf("%s", &person[ret].Address);
    }
}

void EmptyPerson(struct Person *person)//清空通讯录
{
    assert(person);
    ML.EP = 0;
}

void SortPerson(struct Person *person)//按名字排序通讯录
{
    assert(person);
    int i = 0;
    int j = 0;
    for (i = 0; i < ML.EP - 1; i++)
    for (j = 0; j < ML.EP - 1 - i; j++)
    {
        if (strcmp(person[j].Name, person[j + 1].Name)>0)
        {
            struct Person p = person[j];
            person[j] = person[j + 1];
            person[j + 1] = p;
        }
    }
}

void Save()//保存(写入)文件
{
    int i = 0;
    FILE *pfw = fopen("MailList.txt", "w");//按"写"的方式打开文件  

    if (pfw == NULL)//打开文件失败
    {
        perror("open file for write");
        exit(1);//(错误)退出程序
    }

    for (i = 0; i<ML.EP; i++)//将键入内容写入到文件中
    {
        fwrite(&(ML.person[i]), sizeof(struct Person), 1, pfw);
    }

    fclose(pfw);
}

void Load()//加载(读入)文件
{
    int i = 0;
    struct Person tmp = { 0 };

    FILE *pfr = fopen("MailList.txt", "r");//按"读"的方式打开文件 

    if (pfr == NULL)//打开文件失败
    {
        perror("open file for read");
        exit(1);//(错误)退出程序
    }

    fread(&tmp, sizeof(struct Person), 1, pfr);
    while (!feof(pfr))//当未读到文件结尾时
    {
        if (ML.EP == ML.MP)//当前人数达到最大容量时
        {
            Expand();//扩大容量
        }
        ML.person[i] = tmp;
        i++;
        ML.EP++;
        fread(&tmp, sizeof(struct Person), 1, pfr);
    }
}

test.c文件

#define _CRT_SECURE_NO_WARNINGS -1

#include "MailList.h"

void menu()
{
    printf("\n");
    printf("*******************************************\n");
    printf("************  My Mail List  ***************\n");
    printf("**** 1-添加       2-删除        3-查找 ****\n");
    printf("**** 4-清空       5-修改        6-排序 ****\n");
    printf("**** 7-显示       8-扩充        9-缩减 ****\n"); 
    printf("****10-加载                     0-退出 ****\n");
    printf("*******************************************\n");
    printf("\n");
}

void test()
{
    int num = 0;
    InitMailList();

    while (1)
    {
        menu();
        printf("请选择:>");
        scanf("%d", &num);
        switch (num)
        {
        case 1:
            AddPerson(ML.person);
            break;
        case 2:
            DeletePerson(ML.person);
            break;
        case 3:
            SearchPerson(ML.person);
            break;
        case 4:
            EmptyPerson(ML.person);
            break;
        case 5:
            ModifyPerson(ML.person);
            break;
        case 6:
            SortPerson(ML.person);
            break;
        case 7:
            ShowPerson(ML.person);
            break; 
        case 8:
            Expand();
            break; 
        case 9:
            Reduce();
            break;
        case 10:
            Load();
            break;
        case 0:
        {
                  Save();
                  Release();
                  return;
        }
            break;
        default:
            break;
        }
    }
}

int main()
{
    test();
    system("pause");
    return 0;
}

关于feofs()的使用细节,可参照链接:fhttp://blog.csdn.net/a1066570234/article/details/78653862

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、5资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值