0


【C语言进阶】进来抄作业,完善你的通讯录(软工期末大作业可用)


🛰️博客主页:✈️銮同学的干货分享基地

🛰️欢迎关注:👍点赞🙌收藏✍️留言

🛰️系列专栏:💐【进阶】C语言学习

🛰️代码仓库:🎉VS2022_C语言仓库

    **家人们更新不易,你们的👍点赞👍和👉关注👈真的对我真重要,各位路过的友友麻烦多多点赞关注,欢迎你们的私信提问,感谢你们的转发!**

** ***** 关注我,关注我,关注我,***你们将会看到更多的优质内容!!


🏡🏡*** 本文重点 ***🏡🏡:

🚅 优化完善静态通讯录****(源码在结尾) 🚏🚏

🥰前言🥰:

    在上篇文章中我们已经使用我们所学过的**结构体**相关知识,写出了一个**基础版本的通讯录工具**,但是我们也知道这个**基础版本的通讯录工具仍然存在着许多的缺陷**。

    我们注意到,在我们的基础版通讯录中,我们**对输入的值没有合法性检测**,这将会导致,**无论用户输入什么样的值都将会被我们的通讯录存储**,并且**由于输入与反馈的数据类型及格式差异,很有可能会导致输出错误**。并且我们可以回想一下,我们手机里的通讯录在保存好联系人信息后,在我们进行查看时,会**按照类似字典内的排序方式(即****字典排序****)将所有联系人进行排序后反馈**给用户,而在我们基础版的通讯录中,保存的联系人信息还没有经过排序。最后还有**对输出反馈的优化**,相信各位小伙伴们在使用通讯录的时侯,屏幕上的打印反馈信息也应该都不是凌乱的吧。

    而关于上面所说的这些问题,我们今天就将**逐一进行处理**。

一、输入合法性检测🤠:

    关于合法性检测,我们的要求是**对需要进行输入合法性检测的信息进行合法性检测**。例如**输入联系方式时若用户输入非数字字符,则提示用户输入非法**;以及在用户**输入年龄时应当对年龄范围进行限制,超出限制范围则应提示用户输入非法**。

①.对“ 联系方式 ”的合法性检测:

    对联系方式的合法性检测我们认为应当分为两步,首先我们应当**对输入的联系方式内容进行检测**,这里所采用的方式是,对数组内字符串进行**遍历**,在**前11个位置(联系方式为 11 位)每个位置上的字符均为****数字字符**** 0~9 时,则继续向后遍历,全部遍历完成且没有错误后则判断为合法,否则为不合法,提醒用户输入非法并要求用户重新进行输入**:
scanf("%s", p->data[p->sz].tele);
char check1[MAX_TELE] = { 0 };
strcpy(check1, p->data[p->sz].tele);
int i = 0;
int cmp = 0;
//比较变量cmp用于标记各位置上的判断结果
for (i = 0; i < 11; i++)
{
    if ('0' <= check1[i] && check1[i] <= '9')
    {
        cmp = 0;
    }
    else
    {
        cmp = 1;
        break;
    }
}
if (cmp)
{
    printf("您输入的联系方式有误,请重新输入!\n");
}
    接下来我们还要进行联系方式长度检测,我们当前所使用的联系方式通常为 11 位,于是我们就将位数暂且定为11位,并且我们**前面的合法位判断中已经确定了每一位上均为合法**,于是在这里我们**只需要对位数加以判断即可**,我们选择的判断方法是**若第十二位为初始化时的 0(即第十二位没有输入值),则合法,否则不合法**:
if (check1[11] == 0)
//下标从零开始,第十二位下标为11
{
    ;
//若合法则不进行操作,不合法则提示不合法并重新输入
}
else
{
    cmp = 1;
}
    最后我们再对整个循环条件进行判断即可。我们**使用了 do ... while 循环,保证了合法性判断至少进行一次**,并在**判断循环一开始便让判断条件 input 变为 0(假),若在判断结束时仍没有不合法现象,则判断为假跳出循环,合法性判断结束**;若在过程中**判断存在不合法输入,则将其值重新赋为 1,提示不合法后继续进入下一循环**:
int input = 1;
do
{
    input = 0;
    //直接让input为0,若出现不合法则改其值为1继续循环
    //不符合不合法则跳出循环

    printf("请输入联系人联系方式:>");
    scanf("%s", p->data[p->sz].tele);
    char check1[MAX_TELE] = { 0 };
    strcpy(check1, p->data[p->sz].tele);
    int i = 0;
    int cmp = 0;
    //比较变量cmp用于标记各位置上的判断结果
    for (i = 0; i < 11; i++)
    {
        if ('0' <= check1[i] && check1[i] <= '9')
        {
            cmp = 0;
        }
        else
        {
            cmp = 1;
            break;
        }
    }
    if (check1[11] == 0)
    //下标从零开始,第十二位下标为11
    {
        ;
        //若合法则不进行操作,不合法则提示不合法并重新输入
    }
    else
    {
        cmp = 1;
    }
    if (cmp)
    {
        input = 1;
        //不合法继续循环
        printf("您输入的联系方式有误,请重新输入!\n");
    }
} while (input);
    同时我们**对“修改联系人信息”功能中的相关输入也需要采用这样的方式进行合法性判断**:
case 4:
    do
    {
        input_cmp = 0;
        //直接让input_cmp为0,若出现不合法则改其值为1继续循环
        //不符合不合法则跳出循环

        printf("请输入联系人联系方式:>");
        scanf("%s", p->data[x - 1].tele);
        char check1[MAX_TELE] = { 0 };
        strcpy(check1, p->data[x - 1].tele);
        int i = 0;
        int cmp = 0;
        //比较变量cmp用于标记各位置上的判断结果
        for (i = 0; i < 11; i++)
        {
            if ('0' <= check1[i] && check1[i] <= '9')
            {
                cmp = 0;
            }
            else
            {
                cmp = 1;
                break;
            }
        }
        if (check1[11] == 0)
            //下标从零开始,第十二位下标为11
        {
            ;
            //若合法则不进行操作,不合法则提示不合法并重新输入
        }
        else
        {
            cmp = 1;
        }
        if (cmp)
        {
            input_cmp = 1;
            //不合法继续循环
            printf("您输入的联系方式有误,请重新输入!\n");
        }
        else
        {
            printf("修改成功!\n");
        }
    } while (input_cmp);
    PrintContact(p, x - 1);
    input = 0;
    break;

** ②.对“年龄”进行合法性检测:**

    对年龄的合法性检测最为简单,我们**只需要判断用户输入的年龄位于区间 0~100 之间即可,合法则跳出,否则继续循环**:
int input = 1;
do
{
    printf("请输入联系人年龄:>");
    scanf("%d", &(p->data[p->sz].age));
    if (0 <= p->data[p->sz].age && p->data[p->sz].age <= 100)
    {
        input = 0;
    }
    else
    {
        printf("您输入的年龄信息有误,请重新输入!\n");
    }
} while (input);
    同样的,**将“修改联系人信息”功能中的输入以同样的方式进行合法性检测**:
case 3:
    do
    {
        printf("请输入联系人年龄:>");
        scanf("%d", &(p->data[x - 1].age));
        if (0 <= p->data[x - 1].age && p->data[x - 1].age <= 100)
        {
            input_cmp = 0;
            printf("修改成功!\n");
        }
        else
        {
            printf("您输入的年龄信息有误,请重新输入!\n");
        }
    } while (input_cmp);
    PrintContact(p, x - 1);
    input = 0;
    break;

二、字典排序🤑:

    字典排序相对简单,简单来说,就是**按照像字典里那样,根据姓名的排序,将通讯录中联系人信息进行排序**。

    而我们要想进行实现,其实也很简单,我们只需要**像冒泡排序那样进行遍历**,**将每一个联系人的姓名均与下一个联系人进行比较,如果后一个联系人的姓名更靠前,则将二者的信息进行交换,否则继续向后一个进行比较**:
//字典排序:
void sort(contact* p)
{
    int i = 0;
    PeoInfo temp;
    for (i = 0; i < p->sz; i++)
    {
        if (strcmp(p->data[i].name, p->data[i + 1].name) > 0)
        {
            temp = p->data[i + 1];
            p->data[i + 1] = p->data[i];
            p->data[i] = temp;
        }
    }
}
    在这里,我们只需要**再定义一个中间结构体,并通过中间结构体直接交换两个联系人的信息**即可,而不用逐一交换两个联系人的各项信息。

三、反馈优化🤯:

    而关于反馈优化则很简单了。在**优化前**,我们的通讯录小工具运行起来是这个样子的:

    优化前的程序运行结果**肉眼可见的繁杂、凌乱,一团乱麻地堆在一起**。于是我们就需要对小工具的打印反馈过程进行优化。

    我们使用的方法仍然是,**使用 Sleep 命令与 system 命令**,共同协作完成优化工作。

    而关于 Sleep 与 system 命令,我们**前面在对三子棋游戏与扫雷游戏(点击跳转)进行优化时,就已经为大家讲解过了**,这里就不再做过多的赘述,各位小伙伴们可以**通过点击游戏名跳转至我们之前关于这两个命令的讲解部分**进行学习。

四、优化版通讯录全部源码🤩:

** 废话不多说,直接给大家上源码**!

** ①.Contact.h:**

#pragma once

//定义宏常量:
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

//引用头文件:
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<Windows.h>

//选项枚举:
enum Option
{
    Exit,//值为0
    Add,//值为1
    Del,//值为2
    Search,//值为3
    Modify,//值为4
    Print//值为5
};

//联系人信息:
typedef struct PeoInfo
{
    char name[MAX_NAME];
    char sex[MAX_SEX];
    int age;
    char tele[MAX_TELE];
    char addr[MAX_ADDR];
}PeoInfo;

//通讯录调用封装:
typedef struct contact
{
    PeoInfo data[MAX];
    int sz;
}contact;

//函数声明:
void InitContact(contact* p);
void sort(contact* p);
void PrintContact(const contact* p, int x);
void PrintAllContact(const contact* p);
void AddContact(contact* p);
void DelContact(contact* p);
void SearchContact(const contact* p);
void ModifyContact(const contact* p);

** ②.Contact.c:**

#define _CRT_SECURE_NO_WARNINGS 1

#include"Contact.h"

//初始化通讯录:
void InitContact(contact* p)
{
    assert(p);
    p->sz = 0;
    memset(p->data, 0, sizeof(p->data));
    //使用memeset函数将p->data所指向的空间中的数据初始化为0
    //操作的空间大小为sizeof函数所计算出的p->data所指向空间的大小,即整个无联系人数据的结构体数组data所占的空间的大小
}

//字典排序:
void sort(contact* p)
{
    int i = 0;
    PeoInfo temp;
    for (i = 0; i < p->sz; i++)
    {
        if (strcmp(p->data[i].name, p->data[i + 1].name) > 0)
        {
            temp = p->data[i + 1];
            p->data[i + 1] = p->data[i];
            p->data[i] = temp;
        }
    }
}

//打印联系人信息:
void PrintContact(const contact* p, int x)
{
    assert(p);
    printf(" 联系人 :%04d\n", x + 1);
    printf(" 姓  名 :%s\n", p->data[x].name);
    printf(" 性  别 :%s\n", p->data[x].sex);
    printf(" 年  龄 :%d\n", p->data[x].age);
    printf("联系方式:%s\n", p->data[x].tele);
    printf("当前住址:%s\n", p->data[x].addr);
}

//打印全部联系人信息:
void PrintAllContact(const contact* p)
{
    assert(p);
    printf("联系人 姓名                性别  年龄   联系方式      住址\n");
    int i = 0;
    for (i = 0; i < p->sz; i++)
    {
        printf(" %04d  %-20s %-5s %-4d %-12s %-30s\n", i + 1, p->data[i].name, p->data[i].sex, p->data[i].age, p->data[i].tele, p->data[i].addr);
    }
}

//添加联系人:
void AddContact(contact* p)
{
    assert(p);
    if (p->sz == MAX)
    {
        system("cls");
        printf("通讯录空间不足,无法添加新成员!\n");
        Sleep(1500);
        system("cls");
    }
    else
    {
        printf("请输入联系人姓名:>");
        scanf("%s", p->data[p->sz].name);

        printf("请输入联系人性别:>");
        scanf("%s", p->data[p->sz].sex);
        
        //对年龄进行合法性检测:
        int input = 1;
        do
        {
            printf("请输入联系人年龄:>");
            scanf("%d", &(p->data[p->sz].age));
            if (0 <= p->data[p->sz].age && p->data[p->sz].age <= 100)
            {
                input = 0;
            }
            else
            {
                Sleep(1000);
                system("cls");
                printf("您输入的年龄信息有误,请重新输入!\n");
                Sleep(1500);
                system("cls");
                printf("请输入联系人姓名:>%s\n", p->data[p->sz].name);
                printf("请输入联系人性别:>%s\n", p->data[p->sz].sex);
            }
        } while (input);

        //对联系方式进行合法性检测:
        input = 1;
        do
        {
            input = 0;
            //直接让input为0,若出现不合法则改其值为1继续循环
            //不符合不合法则跳出循环

            printf("请输入联系人联系方式:>");
            scanf("%s", p->data[p->sz].tele);
            char check1[MAX_TELE] = { 0 };
            strcpy(check1, p->data[p->sz].tele);
            int i = 0;
            int cmp = 0;
            //比较变量cmp用于标记各位置上的判断结果
            for (i = 0; i < 11; i++)
            {
                if ('0' <= check1[i] && check1[i] <= '9')
                {
                    cmp = 0;
                }
                else
                {
                    cmp = 1;
                    break;
                }
            }
            if (check1[11] == 0)
            //下标从零开始,第十二位下标为11
            {
                ;
                //若合法则不进行操作,不合法则提示不合法并重新输入
            }
            else
            {
                cmp = 1;
            }
            if (cmp)
            {
                input = 1;
                //不合法继续循环
                Sleep(1000);
                system("cls");
                printf("您输入的联系方式有误,请重新输入!\n");
                Sleep(1500);
                system("cls");
                printf("请输入联系人姓名:>%s\n", p->data[p->sz].name);
                printf("请输入联系人性别:>%s\n", p->data[p->sz].sex);
                printf("请输入联系人年龄:>%d\n", p->data[p->sz].age);
            }
        } while (input);
        
        printf("请输入联系人住址:>");
        scanf("%s", p->data[p->sz].addr);
        Sleep(1000);
        system("cls");
        printf("****************************\n");
        printf("****************************\n");
        printf("**** 联系人信息添加成功!***\n");
        printf("****************************\n");
        printf("****************************\n");
        PrintContact(p, p->sz);
        sort(p);
        p->sz++;
    }
}

//删除联系人:
void DelContact(contact* p)
{
    assert(p);
    int num = 0;
    if (p->sz == 0)
    {
        printf("对不起,当前通讯录中没有联系人信息!\n");
        Sleep(1500);
    }
    else
    {
        PrintAllContact(p);
        printf("请输入您想删除的联系人编号:>");
        scanf("%d", &num);
        int x = num - 1;
        if (0 <= x && x <= p->sz)
        {
            int j = 0;
            for (j = x; j < p->sz; j++)
            {
                p->data[j] = p->data[j + 1];
                p->sz--;
            }
            Sleep(1000);
            system("cls");
            printf("**************************\n");
            printf("**************************\n");
            printf("**** 联系人信息已删除!***\n");
            printf("**************************\n");
            printf("**************************\n");
            PrintAllContact(p);
            Sleep(3000);
        }
    }
}

//查询联系人:
void SearchContact(const contact* p)
{
    assert(p);
    char name[MAX_NAME] = { 0 };
    printf("请输入您想要查询的联系人姓名:>");
    scanf("%s", &name);
    Sleep(1000);
    system("cls");
    int i = 0;
    int ret = 1;
    for (i = 0; i < p->data; i++)
    {
        if (0 == strcmp(name, p->data[i].name))
        {
            printf("************************\n");
            printf("************************\n");
            printf("**** 成功找到联系人!***\n");
            printf("************************\n");
            printf("************************\n");
            PrintContact(p, i);
            Sleep(3000);
            ret = 0;
            break;
        }
    }
    if (ret)
    {
        printf("************************\n");
        printf("************************\n");
        printf("**** 未找到该联系人!***\n");
        printf("************************\n");
        printf("************************\n");
        Sleep(1500);
    }
}

//修改联系人信息:
void ModifyContact(contact* p)
{
    assert(p);
    int x = 0;
    int input = 0;
    int input_cmp = 1;
    if (p->sz == 0)
    {
        printf("对不起,当前通讯录中没有联系人信息!\n");
        Sleep(1500);
        system("cls");
    }
    else
    {
        PrintAllContact(p);
        printf("请输入您想要修改的联系人编号:>");
        scanf("%d", &x);
        Sleep(1000);
        system("cls");
        do
        {
            printf("***************************\n");
            printf("***************************\n");
            PrintContact(p, x - 1);
            printf("***************************\n");
            printf("当前支持修改的信息:\n");
            printf("1.Name\n");
            printf("2.Sex\n");
            printf("3.Age\n");
            printf("4.Tele\n");
            printf("5.Addr\n");
            printf("请选择您想要修改的信息:>");
            scanf("%d", &input);
            Sleep(1000);
            system("cls");
            switch (input)
            {
            case 1:
                printf("***************************\n");
                printf("***************************\n");
                PrintContact(p, x - 1);
                printf("***************************\n");
                printf("请更新联系人姓名:");
                scanf("%s", p->data[x - 1].name);
                Sleep(1000);
                system("cls");
                printf("**************************\n");
                printf("**************************\n");
                printf("**** 联系人姓名已修改!***\n");
                printf("**************************\n");
                printf("**************************\n");
                PrintContact(p, x - 1);
                Sleep(3000);
                system("cls");
                input = 0;
                break;
            case 2:
                printf("***************************\n");
                printf("***************************\n");
                PrintContact(p, x - 1);
                printf("***************************\n");
                printf("请更新联系人性别:");
                scanf("%s", p->data[x - 1].sex);
                Sleep(1000);
                system("cls");
                printf("**************************\n");
                printf("**************************\n");
                printf("**** 联系人性别已修改!***\n");
                printf("**************************\n");
                printf("**************************\n");
                PrintContact(p, x - 1);
                Sleep(3000);
                system("cls");
                input = 0;
                break;
            case 3:
                do
                {
                    printf("***************************\n");
                    printf("***************************\n");
                    PrintContact(p, x - 1);
                    printf("***************************\n");
                    printf("请更新联系人年龄:>");
                    scanf("%d", &(p->data[x - 1].age));
                    Sleep(1000);
                    system("cls");
                    if (0 <= p->data[x - 1].age && p->data[x - 1].age <= 100)
                    {
                        input_cmp = 0;
                        printf("**************************\n");
                        printf("**************************\n");
                        printf("**** 联系人年龄已修改!***\n");
                        printf("**************************\n");
                        printf("**************************\n");
                    }
                    else
                    {
                        printf("您输入的年龄信息有误,请重新输入!\n");
                        Sleep(1500);
                        system("cls");
                    }
                } while (input_cmp);
                PrintContact(p, x - 1);
                Sleep(3000);
                system("cls");
                input = 0;
                break;
            case 4:
                do
                {
                    input_cmp = 0;
                    //直接让input_cmp为0,若出现不合法则改其值为1继续循环
                    //不符合不合法则跳出循环

                    printf("***************************\n");
                    printf("***************************\n");
                    PrintContact(p, x - 1);
                    printf("***************************\n");
                    printf("请更新联系人联系方式:>");
                    scanf("%s", p->data[x - 1].tele);
                    Sleep(1000);
                    system("cls");
                    char check1[MAX_TELE] = { 0 };
                    strcpy(check1, p->data[x - 1].tele);
                    int i = 0;
                    int cmp = 0;
                    //比较变量cmp用于标记各位置上的判断结果
                    for (i = 0; i < 11; i++)
                    {
                        if ('0' <= check1[i] && check1[i] <= '9')
                        {
                            cmp = 0;
                        }
                        else
                        {
                            cmp = 1;
                            break;
                        }
                    }
                    if (check1[11] == 0)
                        //下标从零开始,第十二位下标为11
                    {
                        ;
                        //若合法则不进行操作,不合法则提示不合法并重新输入
                    }
                    else
                    {
                        cmp = 1;
                    }
                    if (cmp)
                    {
                        input_cmp = 1;
                        //不合法继续循环
                        printf("您输入的联系方式有误,请重新输入!\n");
                        Sleep(1500);
                        system("cls");
                    }
                    else
                    {
                        printf("******************************\n");
                        printf("******************************\n");
                        printf("**** 联系人联系方式已修改!***\n");
                        printf("******************************\n");
                        printf("******************************\n");
                    }
                } while (input_cmp);
                PrintContact(p, x - 1);
                Sleep(3000);
                system("cls");
                input = 0;
                break;
            case 5:
                printf("***************************\n");
                printf("***************************\n");
                PrintContact(p, x - 1);
                printf("***************************\n");
                printf("请更新联系人住址:");
                scanf("%s", p->data[x - 1].addr);
                Sleep(1000);
                system("cls");
                printf("**************************\n");
                printf("**************************\n");
                printf("**** 联系人住址已修改!***\n");
                printf("**************************\n");
                printf("**************************\n");
                PrintContact(p, x - 1);
                Sleep(3000);
                system("cls");
                input = 0;
                break;
            default:
                printf("您的选择有误,请重新选择!\n");
                Sleep(1500);
                system("cls");
                break;
            }
        }while (input);
    }
}

** ③.test.c:**

#define _CRT_SECURE_NO_WARNINGS 1

#include"Contact.h"

void menu()
{
    printf("**********************************\n");
    printf("**********************************\n");
    printf("******** 欢迎使用本通讯录 ********\n");
    printf("**********************************\n");
    printf("***** 本通讯录现提供以下功能 *****\n");
    printf("************ 1.Add ***************\n");
    printf("************ 2.Del ***************\n");
    printf("************ 3.Search ************\n");
    printf("************ 4.Modify ************\n");
    printf("************ 5.Print *************\n");
    printf("************ 0.Exit **************\n");
    printf("**********************************\n");
    printf("**********************************\n");
}

void Contact()
{
    int input = 0;
    contact con;
    InitContact(&con);
    do
    {
        menu();
        printf("请您进行选择:> ");
        scanf("%d", &input);
        switch (input)
        {
        case Add:
            Sleep(1000);
            system("cls");
            AddContact(&con);
            Sleep(3000);
            system("cls");
            break;
        case Del:
            Sleep(1000);
            system("cls");
            DelContact(&con);
            system("cls");
            break;
        case Search:
            Sleep(1000);
            system("cls");
            SearchContact(&con);
            system("cls");
            break;
        case Modify:
            Sleep(1000);
            system("cls");
            ModifyContact(&con);
            Sleep(1000);
            system("cls");
            break;
        case Print:
            Sleep(1000);
            system("cls");
            PrintAllContact(&con);
            Sleep(1000);
            system("cls");
            break;
        case Exit:
            Sleep(1000);
            system("cls");
            printf("正在退出!\n");
            Sleep(1000);
            system("cls");
            break;
        default:
            Sleep(1000);
            system("cls");
            printf("您的选择有误,请重新选择!\n");
            Sleep(1500);
            system("cls");
            break;
        }
    } while (input);
}

int main()
{
    Contact();

    return 0;
}

🥳总结🥳:

    至此,我们关于**通讯录的优化就全部完成了**。不过我们看到我们目前写出来的通讯录**仍旧功能简单**,各位小伙伴们下去以后可以**自行研究,再给它添加上我们需要的各种功能**!

    🔥🔥***坚强并不只是在大是大非中不屈服,而也是在挫折前不改变自己***🔥🔥

    更新不易,辛苦各位小伙伴们动动小手,**👍三连走一走💕💕 ~ ~ ~  你们真的对我很重要!**最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

本文转载自: https://blog.csdn.net/weixin_59392935/article/details/128410276
版权归原作者 銮崽的干货分享基地 所有, 如有侵权,请联系我们删除。

“【C语言进阶】进来抄作业,完善你的通讯录(软工期末大作业可用)”的评论:

还没有评论