练手项目层初阶1—《详解静态版本——通讯录管理系统》

在这里插入图片描述

🚩前言

俗话说:“学以致用!”,前面描述了C语言的各种知识,接下来,我们就运用所学,自己写一个练手项目——《静态通讯录管理系统》

🔊 项目需求

静态版本通讯录,主要完成对联系人信息的增、删、查、改、排序、显示功能。由于
初级练手项目,主要是为了熟悉和整体运用C语言知识。因此,对联系人的数据保存暂时没写,我会在后面加入保存功能。

📚 项目知识点包含

此练手小项目,主要会运用到结构体、结构体的嵌套、结构体数组、枚举、以及各种增删查改的简单算法,还有就是用分文件编写来管理该系统。其他都是C语言中各种的结构语句。

🧩项目框架

在这里插入图片描述

📝框架拆解分析

接下来对三个文件所包含的内容进行详解——>👇👇👇👇

✨Struct_book.h 头文件解析

在这里插入图片描述

下面对代码进行解析:👇👇

//对需要用到的常量用宏定义来表示,方便以后修改
#define MAX_NUMBER 100
#define MAX_NAME 100
#define MAX_SEX 20
#define MAX_TELE 12
#define MAX_ADDR 300

//枚举所有功能,它的常量刚好可以匹配上我们输入功能的数字。
enum Eu
{
    Exit,//0,退出
    Add,//1,添加
    Del,//2,删除
    Find,//3,查找
    Mod,//4,修改
    Sort,//5,排序
    Show//6,显示
};


//信息结构体
typedef struct PersonInformation
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char TeleNumber[MAX_TELE];
    char addr[MAX_ADDR];
}PeoInfo;
//直接用typedef给结构体struct PersonInformation命名为PeoInfo


//通讯录结构体
typedef struct Contact
{
    PeoInfo data[MAX_NUMBER];//储存联系人数据的结构体数组,
    //每个元素都是结构体类型
    int count;//记录成员数量
}Con;


void InitCon(Con* ptr);//初始化函数
void Add_Person_Information(Con* ptr);//添加函数
void Show_Person_Information(const Con* ptr);//打印信息函数
void Delete_Person_Information(Con* ptr);//删除指定元素信息
void Find_Person_Information(Con* ptr);//查找函数
void Modify_Person_Information(Con* ptr);//修改函数
void Sort_Person_Information(Con* ptr);//排序函数

上述代码中,主要的是:
//信息结构体
typedef struct PersonInformation
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char TeleNumber[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;

掌握结构体创建知识点就可以写出来了。

//通讯录结构体
typedef struct Contact
{
PeoInfo data[MAX_NUMBER];
int count;
}Con;

存储数据主要是结构体数组起的作用,因为用的是数组,存储大小是固定好的,通过宏定义来改变固定值,缺点就是定义小了不够存储,定义大了浪费空间。所以叫静态的通讯录。

✨Struct_book.c文件解析

在这里插入图片描述

下面是选取代码块详解:

void Delete_Person_Information(Con* ptr)
{
  
    assert(ptr);
    if (ptr->count == 0)
    {
        printf("通讯录为空,无信息可删除!\n");
        return;
    }
    printf("请输入要删除的联系人的姓名:\n");
    char name[MAX_NAME];
    scanf("%s", name);

    //查找
   int ret=Find_Information(ptr,name);
   
    //删除
   if (ret == -1)
   {
       printf("没找到,无法删除!\n");
       return;
    }
   for (int i = ret; i < ptr->count - 1; i++)//人数减去1,防止越界
   {
       ptr->data[i] = ptr->data[i + 1];//若删除最后一个也不影响,
       //因为最后人数会减去1
   }
   //人数减去1
   ptr->count--;
   printf("删除成功!\n");
  
   Show_Person_Information(ptr);
}

选取的是删除模块,在此模块需要注意的是循环条件和人数,没删除一个count得自减。

✨test_book.c文件解析

在这里插入图片描述

代码展示:

void menu()
{
    printf("\t\t\t\t**************************\n");
    printf("\t\t\t\t*****  Address Book  *****\n");
    printf("\t\t\t\t**************************\n");
    printf("\t\t\t\t********* 0、Exit ********\n");
    printf("\t\t\t\t********* 1、Add  ********\n");
    printf("\t\t\t\t********* 2、Del  ********\n");
    printf("\t\t\t\t********* 3、Find ********\n");
    printf("\t\t\t\t********* 4、Mod  ********\n");
    printf("\t\t\t\t********* 5、Sort ********\n");
    printf("\t\t\t\t********* 6、Show ********\n");
    printf("\t\t\t\t**************************\n");
}

static void test()
{
    Con con;//创建通讯录结构体变量

    InitCon(&con);//初始化通讯录结构体
   
    int input = 0;
    //menu();
    while(1)
    {
        menu();
        printf("请输入对应的功能——>:\n");
        scanf("%d", &input);
        switch (input)
        {
        case Add:
            Add_Person_Information(&con);
            break;
        case Del:
            Delete_Person_Information(&con);
            break;
        case Find:
            Find_Person_Information(&con);
            break;
        case Mod:
            Modify_Person_Information(&con);
            break;
        case Sort:
            Sort_Person_Information(&con);
            break;
        case Show:
            Show_Person_Information(&con);
            break;
        case Exit:
            printf("退出通讯录,欢迎下次使用!\n");
            exit(1);
        default:
            printf("输入有误,请重新输入:\n");
            break;
        }
        _getch();
        system("cls");//清屏
    }
}

int main()
{
    test();
    return 0;
}

📺演示效果

在这里插入图片描述

在这里插入图片描述

🚀完整代码

Struct_book.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<Windows.h>
#include<conio.h>
#include<assert.h>
#include<stdlib.h>


#define MAX_NUMBER 100
#define MAX_NAME 100
#define MAX_SEX 20
#define MAX_TELE 12
#define MAX_ADDR 300
//枚举所有功能
enum Eu
{
    Exit,
    Add,
    Del,
    Find,
    Mod,
    Sort,
    Show
};


//信息结构体
typedef struct PersonInformation
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char TeleNumber[MAX_TELE];
    char addr[MAX_ADDR];
}PeoInfo;


//通讯录结构体
typedef struct Contact
{
    PeoInfo data[MAX_NUMBER];
    int count;
}Con;


void InitCon(Con* ptr);//初始化函数
void Add_Person_Information(Con* ptr);//添加函数
void Show_Person_Information(const Con* ptr);//打印信息函数
void Delete_Person_Information(Con* ptr);//删除指定元素信息
void Find_Person_Information(Con* ptr);//查找函数
void Modify_Person_Information(Con* ptr);//修改函数
void Sort_Person_Information(Con* ptr);//排序函数


Struct_book.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"Struct_Book.h"

void InitCon(Con* ptr)
{
    assert(ptr);
    ptr->count = 0;
    memset(ptr->data, 0, sizeof(ptr->data));
}


void Add_Person_Information(Con* ptr)
{
   
    assert(ptr);
    if (ptr->count == MAX_NUMBER)
    {
        printf("通讯录已满,无法添加!\n");
        return;
    }
    printf("请输入姓名:\n");
    scanf("%s", ptr->data[ptr->count].name);
    printf("请输入年龄:\n");
    scanf("%d", &(ptr->data[ptr->count].age));
    printf("请输入性别:\n");
    scanf("%s", ptr->data[ptr->count].sex);
    printf("请输入电话:\n");
    scanf("%s", ptr->data[ptr->count].TeleNumber);
    printf("请输入地址:\n");
    scanf("%s", ptr->data[ptr->count].addr);

    ptr->count++;
    printf("添加成功\n");
    Sleep(1000);
    system("cls");
}


void Show_Person_Information(const Con* ptr)
{
   
    assert(ptr);
    if (ptr->count == 0)
    {
        printf("通讯录为空,无法显示!\n");
        return;
    }
   
    printf("\n通讯录总人数:%d\n", ptr->count);
    printf("---------------------------------------------------------------------------------------------\n");

    printf("|%-12s\t\t%-2s\t%-2s\t\t%-12s\t\t%-20s|\n", "姓名", "年龄", "性别", "电话", "地址");
    for (int i = 0; i < ptr->count; i++)
    {
        printf("|%-12s\t\t%-2d\t%-2s\t\t%-12s\t\t%-20s|\n", ptr->data[i].name
            , ptr->data[i].age
            , ptr->data[i].sex
            , ptr->data[i].TeleNumber
            , ptr->data[i].addr);
    }
    printf("---------------------------------------------------------------------------------------------\n");

}

static int Find_Information(Con* pc, char* name1)
{
    assert(pc);
    for (int i = 0; i < pc->count; i++)
    {
        if (strcmp(pc->data[i].name, name1) == 0)//说明两个相同
        {
            return i;//返回当前位置
        }
    }
    //遍历完都没找到
    return -1;
}

void Delete_Person_Information(Con* ptr)
{
  
    assert(ptr);
    if (ptr->count == 0)
    {
        printf("通讯录为空,无信息可删除!\n");
        return;
    }
    printf("请输入要删除的联系人的姓名:\n");
    char name[MAX_NAME];
    scanf("%s", name);

    //查找
   int ret=Find_Information(ptr,name);
   
    //删除
   if (ret == -1)
   {
       printf("没找到,无法删除!\n");
       return;
    }
   for (int i = ret; i < ptr->count - 1; i++)//人数减去1,防止越界
   {
       ptr->data[i] = ptr->data[i + 1];//若删除最后一个也不影响,因为最后人数会减去1
   }
   //人数减去1
   ptr->count--;
   printf("删除成功!\n");
  
   Show_Person_Information(ptr);
}



void Find_Person_Information(Con* ptr)
{
  
    assert(ptr);
    if (ptr->count == 0)
    {
        printf("通讯录为空,无法查找!\n");
        return;
    }
    char name2[MAX_NAME];
    printf("请输入要查找的联系人的姓名:\n");
    scanf("%s", name2);
    int ret = Find_Information(ptr, name2);
    if (ret == -1)
    {
        printf("没找到!\n");
        return;
    }
   
    printf("此联系人信息如下:\n");
    printf("---------------------------------------------------------------------------------------------\n");

    printf("|%-12s\t\t%-2s\t%-2s\t\t%-12s\t\t%-20s|\n", "姓名", "年龄", "性别", "电话", "地址");
    printf("|%-12s\t\t%-2d\t%-2s\t\t%-12s\t\t%-20s|\n", ptr->data[ret].name
        , ptr->data[ret].age
        , ptr->data[ret].sex
        , ptr->data[ret].TeleNumber
        , ptr->data[ret].addr);
    printf("---------------------------------------------------------------------------------------------\n");

}



void Modify_Person_Information(Con* ptr)
{
  
    assert(ptr);
    if (ptr->count==0)
    {
        printf("通讯录为空,无法修改!\n");
        return;
    }
    printf("请输入要修改信息的联系人的姓名:\n");
    char name3[MAX_NAME];
    scanf("%s", name3);
    int ret = Find_Information(ptr, name3);
    if (ret == -1)
    {
        printf("没找到,无法修改!\n");
        return;
    }
    printf("修改进行中………\n");
    printf("请输入新的姓名:\n");
    scanf("%s", ptr->data[ret].name);
    printf("请输入新的年龄:\n");
    scanf("%d", &(ptr->data[ret].age));
    printf("请输入新的性别:\n");
    scanf("%s", ptr->data[ret].sex);
    printf("请输入新的电话:\n");
    scanf("%s", ptr->data[ret].TeleNumber);
    printf("请输入新的地址:\n");
    scanf("%s", ptr->data[ret].addr);
    printf("修改成功!\n");
   
    Show_Person_Information(ptr);
}


int compar_by_name(const void* e1, const void* e2)
{
    return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}

int compar_by_age(const void* e1, const void* e2)
{
    return (((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age);
}


void Sort_Person_Information(Con* ptr)
{ 
 
    int num = 0;
    assert(ptr);
    if (ptr->count == 0)
    {
        printf("通讯录为空,无法排序!\n");
        return;
    }
    printf("\n请选择排序方式:1.姓名首字母、2.年龄排序\n");
    scanf("%d", &num);
    if (num == 1)
    {
        //void qsort (void* base, size_t num, size_t size,int (*compar)(const void*, const void*));
        qsort(ptr,ptr->count,sizeof(PeoInfo),compar_by_name);
        printf("排序成功!\n");
    }
    if (num == 2)
    {
        qsort(ptr, ptr->count, sizeof(PeoInfo), compar_by_age);
        printf("排序成功!\n");
    }
}

test_book.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Struct_Book.h"


void menu()
{
    printf("\t\t\t\t**************************\n");
    printf("\t\t\t\t*****  Address Book  *****\n");
    printf("\t\t\t\t**************************\n");
    printf("\t\t\t\t********* 0、Exit ********\n");
    printf("\t\t\t\t********* 1、Add  ********\n");
    printf("\t\t\t\t********* 2、Del  ********\n");
    printf("\t\t\t\t********* 3、Find ********\n");
    printf("\t\t\t\t********* 4、Mod  ********\n");
    printf("\t\t\t\t********* 5、Sort ********\n");
    printf("\t\t\t\t********* 6、Show ********\n");
    printf("\t\t\t\t**************************\n");
}

static void test()
{
    Con con;//创建通讯录结构体变量

    InitCon(&con);//初始化通讯录结构体
   
    int input = 0;
    //menu();
    while(1)
    {
        menu();
        printf("请输入对应的功能——>:\n");
        scanf("%d", &input);
        switch (input)
        {
        case Add:
            Add_Person_Information(&con);
            break;
        case Del:
            Delete_Person_Information(&con);
            break;
        case Find:
            Find_Person_Information(&con);
            break;
        case Mod:
            Modify_Person_Information(&con);
            break;
        case Sort:
            Sort_Person_Information(&con);
            break;
        case Show:
            Show_Person_Information(&con);
            break;
        case Exit:
            printf("退出通讯录,欢迎下次使用!\n");
            exit(1);
        default:
            printf("输入有误,请重新输入:\n");
            break;
        }
        _getch();
        system("cls");//清屏
    }
}

int main()
{
    test();
    return 0;
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值