【C语言】详解通讯录(初级版本)

作者: 热爱编程的小y
专栏:C语言基础
座右铭:彼方尚有荣光在
【C语言】详解通讯录(初级版本)_第1张图片

一.功能

我们设计的初级通讯录要具备以下功能:

1. 新增联系人
2. 删除联系人
3. 查找联系人
4. 修改联系人
5. 显示所有联系人
6. 按名字排序所有联系人

我们暂且给这个通讯录以100的存储空间,即可以存放100个不同的联系人

二.创立文件

对于初学者来说,通讯录算的上一个工程量较大的代码了,所以我们需要把代码分成一个个模块,便于后续编译与修改,模块型的代码还有个好处,就是可以像积木一样拼接到其他代码上。

我们一般创建三个文件,分别是:

  1. 测试通讯录:test.c

  1. 实现通讯录:contacts.h

  1. 函数的声明:contacts.c

最终呈现在vs上是这样的:

【C语言】详解通讯录(初级版本)_第2张图片

三.设计代码

(一)菜单

依据通讯录的功能,我们可以列出这样的菜单:

void Menu()
{
    printf("***********************************\n");
    printf("**    1.add          2.delete    **\n");
    printf("**    3.search       4.revise    **\n");
    printf("**    5.display      6.sort      **\n");
    printf("**    0.exit                     **\n");
    printf("***********************************\n");
    return;
}

(二)主函数

主体部分我们使用while语句循环,以达到菜单选项多次选择的效果

循环内我们再使用switch语句对不同的选项进行不同的操作,单次操作完成后返回继续循环

主函数代码如下:

int main()
{
    int choice = 0;
    Contact con;    //创建通讯录
    InitContact(&con);    //初始化通讯录
    while (1)
    {
        Menu();    //打印菜单
        printf("选择要进行的操作:");
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            Add_Contacts(&con);
            break;
        case 2:
            Delete_Contacts(&con);
            break;
        case 3:
            Search_Contacts(&con);
            break;
        case 4:
            Revise_Contacts(&con);
            break;
        case 5:
            Display_Contacts(&con);
            break;
        case 6:
            Sort_Contacts(&con);
            break;
        default:
            return 0;
        }
    }
    return 0;
}

效果如下:

【C语言】详解通讯录(初级版本)_第3张图片

(三)建立联系人模板

我们声明一个结构体,把联系人信息全部放到这个结构体当中,并且用typedef对结构体名字重命名,即简化结构体名称,便于后续结构体的定义。

by the way:[]内的参数最好用一个宏来代替,这样做是为了方便后续数值的修改,更能体现通讯录的实用性。

如下:

#define MAX_NAME 20//便于修改数值
#define MAX_SEX 5
#define MAX_ADDR 30
#define MAX_TELE 12
typedef struct PeoInfo
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char addr[MAX_ADDR];
    char tele[MAX_TELE];
}PeoInfo;

(四)定义与初始化通讯录

我们想把联系人信息放在通讯录中,就必须定义一个结构体数组来存放,然而我们要想精准存放的话,也要定义一个变量sz(size)来确保每一个联系人都能依次存放进去

如下:

//定义通讯录
typedef struct Contact
{
    PeoInfo peo[100];
    int sz;
}Contact;

//初始化通讯录
//void InitContact(Contact* pc);//声明通通放在头文件中
void InitContact(Contact* pc)
{
    pc->sz = 0;
    memset(pc->peo, 0, sizeof(pc->peo));
}

完成了上述操作,接下来要做的就是对通讯录各种功能的具体实现了。

(五)功能的具体实现

  1. 新增

在增加联系人之前先要确保通讯录留有一定空间,

在一次输入各种信息之后我们让参数sz往后移一个单位,实现通讯录的连续录入

如下:

void Add_Contacts(Contact* pc)
{
    if (pc->sz == 100)
    {
        printf("通讯录已满,无法添加");
        return;
    }
    printf("输入姓名:");
    scanf("%s", pc->peo[pc->sz].name);
    printf("输入年龄:");
    scanf("%d", &(pc->peo[pc->sz].age));
    printf("输入性别:");
    scanf("%s", pc->peo[pc->sz].sex);
    printf("输入住址:");
    scanf("%s", pc->peo[pc->sz].addr);
    printf("输入号码:");
    scanf("%s", pc->peo[pc->sz].tele);
    pc->sz++;
    return;
}
  1. 删除

同理,在删除联系人之前,也要先确保通讯录内至少存有一个联系人。

我们删除采用从后往前依次赋值的方法,如图所示:

【C语言】详解通讯录(初级版本)_第4张图片

假设下标为9的联系人是要删除的对象,我们一次把下标为10的联系人信息赋给9,下标为11的赋给10……以此类推,最终变成:

【C语言】详解通讯录(初级版本)_第5张图片

如图所示,最后一个元素其实已经不需要了,所以我们只需要把参数sz-1即可把范围缩小。

注意:我们要确保[]内的参数不会超出范围,避免越界的情况发生

如下:

void Delete_Contacts(Contact* pc)
{
    if(sz==0)
    {
        printf("没有可删除的对象");
        return;
    }
    char name[MAX_NAME] = {"\0"};
    printf("请输入要删除的联系人:");
    scanf("%s", name);
    int del = 0;
    for (int i = 0; i < pc->sz-1; i++)
    {
        if (strcmp(pc->peo[i].name, name) == 0)
        {
            del = i;
            break;
        }
    }
    for (int i = del; i < pc->sz - 1; i++)
    {
        pc->peo[i] = pc->peo[i+1];
    }
    pc->sz--;
    printf("删除成功\n");
    return;
}
  1. 查找

同理,也要先确保通讯录内至少存有一个联系人。

我们通过for循环依次查找名字是否匹配,名字是以字符串的形式保存,比较两个字符串一不一样,想到了谁?没错,那就是strcmp函数,如果其返回值为0,则找到

注意:要想让打印出来的数据更好看,我们可以用%后面跟数字的方式让它们对其,正数则靠右对齐,负数则靠左对齐,这里我们选择左对齐

如下:

void Search_Contacts(Contact* pc)
{
    if(sz==0)
    {
        printf("没有可查找的对象");
        return;
    }
    char name[MAX_NAME] = { "\0" };
    printf("请输入要查找的联系人:");
    scanf("%s", name);
    int ser=0;
    for (int i = 0; i < pc->sz - 1; i++)
    {
        if (strcmp(pc->peo[i].name, name) == 0)
        {
            ser = i;
            break;
        }
    }
    printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n", "名字", "年龄", "性别", "住址", "电话");
    printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n", pc->peo[ser].name,
        pc->peo[ser].age,
        pc->peo[ser].sex,
        pc->peo[ser].addr,
        pc->peo[ser].tele);
    return;
}
  1. 修改

同理……不说了

修改就是建立在查找基础之上。代码前半部分基本相同,后半部分新增一串联系人信息即可。

如下:

void Revise_Contacts(Contact* pc)
{
    if(sz==0)
    {
        printf("没有可修改的对象");
        return;
    }
    char name[MAX_NAME] = { "\0" };
    printf("请输入要修改的联系人:");
    scanf("%s", name);
    int rev;
    for (int i = 0; i < pc->sz - 1; i++)
    {
        if (strcmp(pc->peo[i].name, name) == 0)
        {
            rev = i;
            break;
        }
    }
    printf("输入修改后的内容:\n");
    printf("输入姓名:");
    scanf("%s", pc->peo[rev].name);
    printf("输入年龄:");
    scanf("%d", &(pc->peo[rev].age));
    printf("输入性别:");
    scanf("%s", pc->peo[rev].sex);
    printf("输入住址:");
    scanf("%s", pc->peo[rev].addr);
    printf("输入号码:");
    scanf("%s", pc->peo[rev].tele);
    printf("修改成功\n");
    return;
}
  1. 显示全部联系人

同……不知道第几次理

我们只需要通过循环语句依次打印即可

如下:

void Display_Contacts(Contact* pc)
{
    if(sz==0)
    {
        printf("没有可显示的对象");
        return;
    }
    printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n", "名字", "年龄", "性别", "住址", "电话");
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n", pc->peo[i].name, 
            pc->peo[i].age, 
            pc->peo[i].sex, 
            pc->peo[i].addr, 
            pc->peo[i].tele);
    }
}
  1. 按名字排序

我们通过strcmp函数对相邻的联系人的名字进行比较,较小者排前面。

如下:

void Sort_Contacts(Contact* pc)
{
    if(sz==0)
    {
        printf("没有可排序的对象");
        return;
    int i = 0;
    int j = 0;
    for (i = 0; i < pc->sz - 1; i++)
    {
        for (j = 0; j < pc->sz - i - 1; j++)
        {
            if (strcmp(pc->peo[j].name, (pc->peo[j + 1]).name) > 0)
            {
                PeoInfo tmp;
                tmp = pc->peo[j];
                pc->peo[j] = pc->peo[j + 1];
                pc->peo[j + 1] = tmp;
            }
        }
    }
    printf("排序成功\n");
    return;
}

四.代码呈现

test.c部分:

#define _CRT_SECURE_NO_WARNINGS 1
#include"contacts.h"
void Menu()
{
    printf("***********************************\n");
    printf("**    1.add          2.delete    **\n");
    printf("**    3.search       4.revise    **\n");
    printf("**    5.display      6.sort      **\n");
    printf("**    0.exit                     **\n");
    printf("***********************************\n");
    return;
}

int main()
{
    int choice = 0;
    Contact con;    //创建通讯录
    InitContact(&con);    //初始化通讯录
    while (1)
    {
        Menu();    //打印菜单
        printf("选择要进行的操作:");
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            Add_Contacts(&con);
            break;
        case 2:
            Delete_Contacts(&con);
            break;
        case 3:
            Search_Contacts(&con);
            break;
        case 4:
            Revise_Contacts(&con);
            break;
        case 5:
            Display_Contacts(&con);
            break;
        case 6:
            Sort_Contacts(&con);
            break;
        default:
            return 0;
        }
    }
    return 0;
}

contacts.h部分:

#pragma once
#define MAX_NAME 20//便于修改数值
#define MAX_SEX 5
#define MAX_ADDR 30
#define MAX_TELE 12
#include
#include

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

//定义通讯录
typedef struct Contact
{
    PeoInfo peo[100];
    int sz;
}Contact;

//初始化通讯录
void InitContact(Contact* pc);

//打印菜单
void Menu();

//1. 添加联系人
void Add_Contacts(Contact* pc);

//2. 删除联系人
void Delete_Contacts(Contact* pc);

//3. 查找联系人
void Search_Contacts(const Contact* pc);

//4. 修改联系人
void Revise_Contacts(Contact* pc);

//5. 显示联系人
void Display_Contacts(const Contact* pc);

//6. 按名字排序联系人
void Sort_Contacts(Contact* pc);

contacts.c部分:

#define _CRT_SECURE_NO_WARNINGS 1
#include"contacts.h"

//初始化
void InitContact(Contact* pc)
{
    pc->sz = 0;
    memset(pc->peo, 0, sizeof(pc->peo));
}

//增
void Add_Contacts(Contact* pc)
{
    if (pc->sz == 100)
    {
        printf("通讯录已满,无法添加");
        return;
    }
    printf("输入姓名:");
    scanf("%s", pc->peo[pc->sz].name);
    printf("输入年龄:");
    scanf("%d", &(pc->peo[pc->sz].age));
    printf("输入性别:");
    scanf("%s", pc->peo[pc->sz].sex);
    printf("输入住址:");
    scanf("%s", pc->peo[pc->sz].addr);
    printf("输入号码:");
    scanf("%s", pc->peo[pc->sz].tele);
    pc->sz++;
    return;
}

//删
void Delete_Contacts(Contact* pc)
{
    char name[MAX_NAME] = {"\0"};
    printf("请输入要删除的联系人:");
    scanf("%s", name);
    int del = 0;
    for (int i = 0; i < pc->sz-1; i++)
    {
        if (strcmp(pc->peo[i].name, name) == 0)
        {
            del = i;
            break;
        }
    }
    for (int i = del; i < pc->sz - 1; i++)
    {
        pc->peo[i] = pc->peo[i+1];
    }
    pc->sz--;
    printf("删除成功\n");
    return;
}

//查
void Search_Contacts(const Contact* pc)
{
    char name[MAX_NAME] = { "\0" };
    printf("请输入要查找的联系人:");
    scanf("%s", name);
    int ser=0;
    for (int i = 0; i < pc->sz - 1; i++)
    {
        if (strcmp(pc->peo[i].name, name) == 0)
        {
            ser = i;
            break;
        }
    }
    printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n", "名字", "年龄", "性别", "住址", "电话");
    printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n", pc->peo[ser].name,
        pc->peo[ser].age,
        pc->peo[ser].sex,
        pc->peo[ser].addr,
        pc->peo[ser].tele);
    return;
}

//改
void Revise_Contacts(Contact* pc)
{
    char name[MAX_NAME] = { "\0" };
    printf("请输入要修改的联系人:");
    scanf("%s", name);
    int rev;
    for (int i = 0; i < pc->sz - 1; i++)
    {
        if (strcmp(pc->peo[i].name, name) == 0)
        {
            rev = i;
            break;
        }
    }
    printf("输入修改后的内容:\n");
    printf("输入姓名:");
    scanf("%s", pc->peo[rev].name);
    printf("输入年龄:");
    scanf("%d", &(pc->peo[rev].age));
    printf("输入性别:");
    scanf("%s", pc->peo[rev].sex);
    printf("输入住址:");
    scanf("%s", pc->peo[rev].addr);
    printf("输入号码:");
    scanf("%s", pc->peo[rev].tele);
    printf("修改成功\n");
    return;
}

//显示
void Display_Contacts(const Contact* pc)
{
    printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\t\n", "名字", "年龄", "性别", "住址", "电话");
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
        printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\t\n", pc->peo[i].name, 
            pc->peo[i].age, 
            pc->peo[i].sex, 
            pc->peo[i].addr, 
            pc->peo[i].tele);
    }
}

//排序
void Sort_Contacts(Contact* pc)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < pc->sz - 1; i++)
    {
        for (j = 0; j < pc->sz - i - 1; j++)
        {
            if (strcmp(pc->peo[j].name, (pc->peo[j + 1]).name) > 0)
            {
                PeoInfo tmp;
                tmp = pc->peo[j];
                pc->peo[j] = pc->peo[j + 1];
                pc->peo[j + 1] = tmp;
            }
        }
    }
    printf("排序成功\n");
    return;
}

结语:

代码还有不完善的地方,欢迎老铁们在评论区交流指正,觉得本篇文章还有价值的,请三连支持一下~~

你可能感兴趣的:(C语言基础,c语言,开发语言)