C语言课程实践:通讯录管理

这是一个大一上学期期末的c语言课程实践作业,比较简单,用到的都是基础知识。

首先看题目:

题目3:通讯录程序设计

设计一个实用的小型通讯录程序,具有添加,查询和删除功能。由姓名,籍贯,电话号码1,电话号码2,电子邮箱组成,姓名可以由字符和数字混合编码。电话号码可由字符和数字组成。(用文件保存)实现功能:

(1)信息录入功能

(2)信息浏览功能

(3)信息查询功能

(4)信息修改功能

确定选题之后,我做的第一步是分析题目要求:

要求:

  1. 添加

因为要录入的信息是str和int混合的,所以我决定使用结构体数组来储存信息。

为了更人性化的设计,我想到了新建联系人列表和添加联系人(后期才想到的)

  1. 删除

因为是结构体数组,思路是先定位要删除的人,再用后面的数据直接覆盖,跟普通数组一样

  1. 查询

利用字符串的对比,遍历所有数据

其次,将录入或者修改的信息用二进制文件保存

思路:录入数据:先输入数据——>打开文件——>写入数据——>保存(关闭文件)

修改数据(增,删,查,找):打开文件——>读取数据——>关闭文件——>修改数据——>打开文件——>写入数据——>保存(关闭文件)

ok,这个程序的总体思路就是这样,多次重复使用的部分用函数封装,最后各部分代码如下:

part1:

根据题目要求储存的信息定义结构体数组

struct phonebook
{
    char name[20];//用户姓名
    char origin[20];//籍贯
    char num1[12];//电话号码1
    char num2[12];//电话号码2
    char email[20];//邮箱
};

part2:

主函数如下:

int main()
{
    void meanu();
    int new_info(phonebook * p);
    void save(phonebook * p, int num);
    void readput(phonebook * p);
    void del_info(phonebook * p,int num);
    int doc_long(phonebook * p);
    void read(phonebook * p, int n);
    void output(phonebook * p, int num);
    void search(phonebook * p, int num);
    void modify(phonebook * p, int num);
    int add_info(phonebook * p, int num);
    void clear();
    phonebook phone[100];
    phonebook* p;
    int n = 0;
    int doc_num = 0;
    int c, add_times = 0;
    p = phone;
    meanu();
    scanf_s("%d", &c);
    switch (c)
    {
    case 1:n =new_info(p); save(p,n); break;
    case 2:doc_num = doc_long(p); read(p, doc_num); del_info(phone, doc_num);save(p, doc_num-1); break;
    case 3:doc_num = doc_long(p); read(p, doc_num); output(p, doc_num); break;
    case 4:doc_num = doc_long(p); read(p, doc_num); search(p,doc_num); break;
    case 5:doc_num = doc_long(p); read(p, doc_num); modify(p, doc_num); save(p, doc_num); break;
    case 6:doc_num = doc_long(p); read(p, doc_num); n = add_info(p, doc_num); save(p,n); break;
    case 7:clear(); break;
    case 8:break; break;
    }
}

part3:

各个子函数如下:

meanu(菜单)

/*
功能:显示菜单
返回值 无
*/
void meanu()
{
    printf("*******************************************************通讯录菜单*******************************************************\n");
    printf("                1:新建通讯录                        ");
    printf("2:删除联系人信息\n");
    printf("              3:浏览联系人信息                    ");
    printf("4:查询联系人信息\n");
    printf("              5:修改联系人信息                    ");
    printf("6:添加联系人信息\n");
    printf("              7:清空通讯录                        ");
    printf("8:退出系统\n");
}

new_info

/*
功能:输入联系人信息
参数 p:结构体数组指针
返回值 输入信息条数
*/
int new_info(phonebook *p)
{
    int n;
    char name[20];
    n = 0;
    printf("新建通讯录:\n");
    printf("请输入姓名:");
    getchar();#吸收换行符号(否则换行符会被gets_s吸收)
    gets_s(p->name);
    strcpy(name, p->name);
    if (strcmp(name, "stop") != 0)//控制程序的结束
    {
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    while (strcmp(name, "stop") != 0)//首次输入姓名时不为stop,第二次输入执行这行
    {
        printf("请输入姓名:");
        gets_s(p->name);
        strcpy(name, p->name);
        if (strcmp(name, "stop") == 0)
            break;
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;//指针自增,指向下一条数据
    }
    return n;//记录输入数据的条数,并且返回,后续配合
}

save函数:保存数据

/*
功能 :保存数据
参数:p:结构体数组指针
      num:要保存的数据的条数
*/
void save(phonebook* p,int num)
{
    FILE* fp;
    fp = fopen("phonebook_data", "wb");//生成新文件
    fwrite(p, sizeof(phonebook), num, fp);//写文件
    fclose(fp);//关闭文件
}

接收new_info返回的数据条数,并且保存数据,

new_info和save配合使用即可输入并且保存数据(实现菜单中的第一个功能)

case 1:n =new_info(p); save(p,n); break;

doc_long(获取文件中数据的条数)

/*
功能 :获取文件中数据条数
参数:p:结构体数组指针
返回值 文件中数据条数
*/
int doc_long(phonebook* p)
{
    FILE* fp;
    int doc_num = 0;
    fp = fopen("phonebook_data", "rb");
    while (1)
    {
        fread(p, sizeof(phonebook), 1, fp);
        
        if (feof(fp))
            break;
        doc_num++;
    }
    fclose(fp);
    return doc_num;
}

由于本人才疏学浅,学识有限,只能做到执行一次程序只使用一个功能,所以我要读取之前保存的数据的时候会遇到一个尴尬的问题:无法知道文件中数据的条数,所以doc_long这个函数应运而生。

在获得了数据的条数之后,便可以读取数据:

read

/*
功能 :读取文件
参数:p:结构体数组指针
      num:要读取数据的条数
*/
void read(phonebook* p, int num)
{
    FILE* fp;
    fp = fopen("phonebook_data", "rb");
    fread(p, sizeof(phonebook), num, fp);
    fclose(fp);
}

由此第二个功能,删除联系人即可实现

del_info

/*
功能 :删除指定联系人数据
参数:p:结构体数组指针
      num:数据条数
*/
void del_info(phonebook* p,int num)
{
    int success = 0;//判断是否删除成功
    phonebook phone[100];
    char del_name[20];
    int n = 0;//用来遍历数组
    int c = 0;//获取索引值
    printf("删除联系人信息\n");
    printf("请输入你要删除的名字:");
    getchar();
    gets_s(del_name);
    for (n; n < num; n++)//遍历结构体数组
    {
        if (strcmp(del_name, p->name) == 0)
        {
            c = n;
            for (c; c < num+2; c++)
            {
                *(p) = *(p+1);//覆盖要删除的信息
                p++;
            }
            printf("删除%s的信息成功\n", del_name);
            success = 1;
        }
        p++;
    }
    if (success != 1)
    {
        printf("抱歉,没有找到%s\n", del_name);
    }
}

output:输出联系人信息

/*
功能 :输出联系人信息
参数:p:结构体数组指针
      num:要输出的数据的条数
*/
void output(phonebook* p, int num)
{
    if (num == 0)
    {
        printf("通讯录为空,请先新建通讯录");
    }
    for (int a = 0; a < num; a++)
    {
        printf("姓名:%s\n", p->name);
        printf("籍贯:%s\n", p->origin);
        printf("号码1:%s\n", p->num1);
        printf("号码2:%s\n", p->num2);
        printf("邮箱:%s\n", p->email);
        printf("\n");
        p++;
    }
}

写这个功能的时候我遇到一个问题,就是无论我文件里面有几条数据,我只能输出第一位联系人的信息,后来我发现是因为我的指针没有自增,因此,指针的自增是非常重要的

doc_num = doc_long(p); read(p, doc_num); output(p, doc_num); break;

配合doc_long read两个函数,可以轻松实现输出联系人的功能

search:查找某一人的信息

void search(phonebook* p, int num)
{
    printf("查询联系人信息\n");
    printf("请输入姓名以搜索:");
    char name[20];
    int success = 0;
    getchar();
    gets_s(name);
    for (int i = 0; i < num; i++)
    {
        if (strcmp(name, p->name) == 0)
        {
            printf("查询到的联系人信息如下:\n");
            printf("姓名:%s\n", p->name);
            printf("籍贯:%s\n", p->origin);
            printf("号码1:%s\n", p->num1);
            printf("号码2:%s\n", p->num2);
            printf("邮箱:%s\n", p->email);
            printf("\n");
            success = 1;
        }
        p++;
    }
    if (success != 1)
    {
        printf("抱歉,没有找到该联系人\n");
    }
}

方法跟删除联系人的时候是一样的,我直接照搬上面的代码,再稍微修改一下

modify:修改联系人信息

/*
功能 :修改联系人信息
参数:p:结构体数组指针
      num:联系人数目
*/
void modify(phonebook* p, int num)
{
    printf("修改联系人信息\n");
    printf("请输入要修改的名字:");
    char name[20];
    int success = 0;//判断是否修改成功
    getchar();
    gets_s(name);
    for (int i = 0; i < num; i++)
    {
        if (strcmp(name, p->name) == 0)
        {
            printf("请输入姓名:");
            gets_s(p->name);
            printf("请输入籍贯:");
            gets_s(p->origin);
            printf("请输入电话号码1:");
            gets_s(p->num1);
            printf("请输入电话号码2:");
            gets_s(p->num2);
            printf("请输入电子邮箱:");
            gets_s(p->email);
            printf("\n");
            success = 1;
            printf("修改成功\n");
        }
        p++;
    }
    if (success != 1)
    {
        printf("抱歉,没有找到该联系人\n");
    }
}

add_info:增加联系人信息

/*
功能 :添加联系人信息
参数:p:结构体数组指针
      num:原有的联系人数量
返回值:添加完后总共的联系人数量
*/
int add_info(phonebook* p, int num)
{
    int c = 0;
    int n;
    char name[20];
    n = 0;
    while (c < num)
    {
        c++;
        p++;
    }
    printf("请输入姓名:");
    getchar();
    gets_s(p->name);
    strcpy(name, p->name);
    if (strcmp(name, "stop") != 0)
    {
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    while (strcmp(name, "stop") != 0)
    {
        printf("请输入姓名:");
        gets_s(p->name);//
        strcpy(name, p->name);
        if (strcmp(name, "stop") == 0)
            break;
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    n = n + num;
    return n;//返回添加完成后的联系人数目
}

此功能一开始写的时候是比较棘手的,没啥头绪,卡了我比较久的一个功能。后来一想,也没有那么难

思路:先把指针移动到当前数组的最后,再在数组的末尾添加数据就好了

clear:清空通讯录

/*
功能 :清空通讯录
*/
void clear()
{
    int sure;
    printf("你确定要清空通讯录吗?\n");
    printf("确认请输入1\n取消请输入0\n");
    scanf_s("%d", &sure);
    if (sure == 1)
    {
        FILE* fp;
        fp = fopen("phonebook_data", "w");
        fclose(fp);
        printf("清空成功");
    }
    if (sure== 0)
        printf("已取消");
}

最后附上我的完整程序:

#include <iostream>

struct phonebook
{
    char name[20];
    char origin[20];
    char num1[12];
    char num2[12];
    char email[20];
};

int main()
{
    void meanu();
    int new_info(phonebook * p);
    void save(phonebook * p, int num);
    void readput(phonebook * p);
    void del_info(phonebook * p,int num);
    int doc_long(phonebook * p);
    void read(phonebook * p, int n);
    void output(phonebook * p, int num);
    void search(phonebook * p, int num);
    void modify(phonebook * p, int num);
    int add_info(phonebook * p, int num);
    void clear();
    phonebook phone[100];
    phonebook* p;
    int n = 0;
    int doc_num = 0;
    int c, add_times = 0;
    p = phone;
    meanu();
    scanf_s("%d", &c);
    switch (c)
    {
    case 1:n =new_info(p); save(p,n); break;
    case 2:doc_num = doc_long(p); read(p, doc_num); del_info(phone, doc_num);save(p, doc_num-1); break;
    case 3:doc_num = doc_long(p); read(p, doc_num); output(p, doc_num); break;
    case 4:doc_num = doc_long(p); read(p, doc_num); search(p,doc_num); break;
    case 5:doc_num = doc_long(p); read(p, doc_num); modify(p, doc_num); save(p, doc_num); break;
    case 6:doc_num = doc_long(p); read(p, doc_num); n = add_info(p, doc_num); save(p,n); break;
    case 7:clear(); break;
    case 8:break; break;
    }
}
/*
功能:显示菜单
返回值 无
*/
void meanu()
{
    printf("*******************************************************通讯录菜单*******************************************************\n");
    printf("                1:新建通讯录                        ");
    printf("2:删除联系人信息\n");
    printf("              3:浏览联系人信息                    ");
    printf("4:查询联系人信息\n");
    printf("              5:修改联系人信息                    ");
    printf("6:添加联系人信息\n");
    printf("              7:清空通讯录                        ");
    printf("8:退出系统\n");
}
/*
功能:输入联系人信息
参数 p:结构体数组指针
返回值 输入信息条数
*/
int new_info(phonebook *p)
{
    int n;
    char name[20];
    n = 0;
    printf("新建通讯录:\n");
    printf("请输入姓名:");
    getchar();
    gets_s(p->name);
    strcpy(name, p->name);
    if (strcmp(name, "stop") != 0)
    {
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    while (strcmp(name, "stop") != 0)
    {
        printf("请输入姓名:");
        gets_s(p->name);//
        strcpy(name, p->name);
        if (strcmp(name, "stop") == 0)
            break;
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    return n;
}
/*
功能 :保存数据
参数:p:结构体数组指针
      num:要保存的数据的条数
*/
void save(phonebook* p,int num)
{
    FILE* fp;
    fp = fopen("phonebook_data", "wb");//生成新文件
    fwrite(p, sizeof(phonebook), num, fp);//写文件
    fclose(fp);//关闭文件
}
/*
功能 :删除指定联系人数据
参数:p:结构体数组指针
      num:数据条数
*/
void del_info(phonebook* p,int num)
{
    int success = 0;
    phonebook phone[100];
    char del_name[20];
    int n = 0;
    int c = 0;
    printf("删除联系人信息\n");
    printf("请输入你要删除的名字:");
    getchar();
    gets_s(del_name);
    for (n; n < num; n++)//遍历结构体数组
    {
        if (strcmp(del_name, p->name) == 0)
        {
            c = n;
            for (c; c < num+2; c++)
            {
                *(p) = *(p+1);
                p++;
            }
            printf("删除%s的信息成功\n", del_name);
            success = 1;
        }
        p++;
    }
    if (success != 1)
    {
        printf("抱歉,没有找到%s\n", del_name);
    }
}
/*
功能 :获取文件中数据条数
参数:p:结构体数组指针
返回值 文件中数据条数
*/
int doc_long(phonebook* p)
{
    FILE* fp;
    int doc_num = 0;
    fp = fopen("phonebook_data", "rb");
    while (1)
    {
        fread(p, sizeof(phonebook), 1, fp);
        
        if (feof(fp))
            break;
        doc_num++;
    }
    fclose(fp);
    return doc_num;
}
/*
功能 :读取文件
参数:p:结构体数组指针
      num:要读取数据的条数
*/
void read(phonebook* p, int num)
{
    FILE* fp;
    fp = fopen("phonebook_data", "rb");
    fread(p, sizeof(phonebook), num, fp);
    fclose(fp);
}
/*
功能 :输出联系人信息
参数:p:结构体数组指针
      num:要输出的数据的条数
*/
void output(phonebook* p, int num)
{
    if (num == 0)
    {
        printf("通讯录为空,请先新建通讯录");
    }
    for (int a = 0; a < num; a++)
    {
        printf("姓名:%s\n", p->name);
        printf("籍贯:%s\n", p->origin);
        printf("号码1:%s\n", p->num1);
        printf("号码2:%s\n", p->num2);
        printf("邮箱:%s\n", p->email);
        printf("\n");
        p++;
    }
}
/*
功能 :搜索联系人信息
参数:p:结构体数组指针
      num:联系人数目
*/
void search(phonebook* p, int num)
{
    printf("查询联系人信息\n");
    printf("请输入姓名以搜索:");
    char name[20];
    int success = 0;
    getchar();
    gets_s(name);
    for (int i = 0; i < num; i++)
    {
        if (strcmp(name, p->name) == 0)
        {
            printf("查询到的联系人信息如下:\n");
            printf("姓名:%s\n", p->name);
            printf("籍贯:%s\n", p->origin);
            printf("号码1:%s\n", p->num1);
            printf("号码2:%s\n", p->num2);
            printf("邮箱:%s\n", p->email);
            printf("\n");
            success = 1;
        }
        p++;
    }
    if (success != 1)
    {
        printf("抱歉,没有找到该联系人\n");
    }
}
/*
功能 :修改联系人信息
参数:p:结构体数组指针
      num:联系人数目
*/
void modify(phonebook* p, int num)
{
    printf("修改联系人信息\n");
    printf("请输入要修改的名字:");
    char name[20];
    int success = 0;//判断是否修改成功
    getchar();
    gets_s(name);
    for (int i = 0; i < num; i++)
    {
        if (strcmp(name, p->name) == 0)
        {
            printf("请输入姓名:");
            gets_s(p->name);
            printf("请输入籍贯:");
            gets_s(p->origin);
            printf("请输入电话号码1:");
            gets_s(p->num1);
            printf("请输入电话号码2:");
            gets_s(p->num2);
            printf("请输入电子邮箱:");
            gets_s(p->email);
            printf("\n");
            success = 1;
            printf("修改成功\n");
        }
        p++;
    }
    if (success != 1)
    {
        printf("抱歉,没有找到该联系人\n");
    }
}
/*
功能 :添加联系人信息
参数:p:结构体数组指针
      num:原有的联系人数量
返回值:添加完后总共的联系人数量
*/
int add_info(phonebook* p, int num)
{
    int c = 0;
    int n;
    char name[20];
    n = 0;
    while (c < num)
    {
        c++;
        p++;
    }
    printf("请输入姓名:");
    getchar();
    gets_s(p->name);
    strcpy(name, p->name);
    if (strcmp(name, "stop") != 0)
    {
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    while (strcmp(name, "stop") != 0)
    {
        printf("请输入姓名:");
        gets_s(p->name);//
        strcpy(name, p->name);
        if (strcmp(name, "stop") == 0)
            break;
        printf("请输入籍贯:");
        gets_s(p->origin);
        printf("请输入电话号码1:");
        gets_s(p->num1);
        printf("请输入电话号码2:");
        gets_s(p->num2);
        printf("请输入电子邮箱:");
        gets_s(p->email);
        n++;
        p++;
    }
    n = n + num;
    return n;//返回添加完成后的联系人数目
}
/*
功能 :清空通讯录
*/
void clear()
{
    int sure;
    printf("你确定要清空通讯录吗?\n");
    printf("确认请输入1\n取消请输入0\n");
    scanf_s("%d", &sure);
    if (sure == 1)
    {
        FILE* fp;
        fp = fopen("phonebook_data", "w");
        fclose(fp);
        printf("清空成功");
    }
    if (sure== 0)
        printf("已取消");
}

总结:整个作业写下来,并不是一帆风顺的,文章开头提到的那些思路也不是从一开始就想到的,是在不断写程序的过程中总结出来的,怎样写方便,怎样写简单,都是慢慢摸索的,有一种船到桥头自然直的感觉,使我这次实践受益匪浅。

以上就是一位c语言初学者的一份期末作业,希望分享给和我一样的初学者一起交流,如果有什么改进方案或者错误的地方·,请务必私信我,谢谢

我后续对该作业进行了改进,解决了新增联系人重名的问题以及输入邮箱格式不正确两种情况,有需要的朋友门也可以联系我

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值