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

在这里插入图片描述

文章目录

  • 🚩前言
    • 🔊 项目需求
    • 📚 项目知识点包含
    • 🧩项目框架
    • 📝框架拆解分析
      • ✨Struct_book.h 头文件解析
      • ✨Struct_book.c文件解析
      • ✨test_book.c文件解析
    • 📺演示效果
    • 🚀完整代码

🚩前言

俗话说:“学以致用!”,前面描述了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;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/515008.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

联想 Y9000P 连接网线速度慢 的 问题解决

参考帖子&#xff1a;求助&#xff0c;拯救者Y9000P 2022 i73060版本 有线网非常慢 无线网正常【笔记本吧】_百度贴吧 问题原因&#xff1a; 网卡驱动版本不对。不能用Win11版&#xff0c;要用Win10版。 问题解决&#xff1a; 1、卸载原驱动 2、下载Win10 驱动 并安装 下载…

C语言——常用库函数的使用及模拟实现

C语言编译系统为使用者提供了很多的预定义库函数。用户在编写程序时&#xff0c;可以直接调用这些库函数。这里选择了一些常用的库函数&#xff0c;简单介绍各个函数的使用方法&#xff1a; 字符串函数 字符串函数函数分为长度不受限制的字符串函数&#xff0c;和长度受限制的…

手搓链表(java)(不完整)

手搓链表&#xff08;java&#xff09;&#xff08;不完整&#xff09; 文章目录 手搓链表&#xff08;java&#xff09;&#xff08;不完整&#xff09;前言一、代码1.MyLinkedList类&#xff1a;2.测试类&#xff1a; 总结 前言 提示&#xff1a;以下是本篇文章正文内容&…

Git 术语及中英文对照

完毕&#xff01;&#xff01;感谢您的收看 ----------★★历史博文集合★★---------- 我的零基础Python教程&#xff0c;Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字…

保姆级教程——VLAN综合实验(不同VLAN通过动态路由访问外网)

前言&#xff1a; 部署了VLAN的传统交换机不能实现不同VLAN间的二层报文转发&#xff0c;因此必须引入路由技术来实现不同VLAN间的通信。VLAN路由可以通过二层交换机配合路由器来实现&#xff0c;也可以通过三层交换机来实现 VLAN间通信的限制 每个VLAN都是一个独立的…

vue 使用自定义标签URL Protocol 调用本地exe 并传参

创建注册表文件reg&#xff0c;并运行 里面的路径需要替换成实际exe的绝对路径 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\App] "URL:App Protocol Handler" "URL Protocol""" [HKEY_CLASSES_ROOT\App\DefaultIcon] &qu…

启动mysql

删除C:\Program Files (x86)\MySQL\MySQL Server 5.7这个路径下的data文件夹&#xff0c;这个很难删除&#xff0c;因为一开机&#xff0c;mysql的某些服务就启动了&#xff0c;每次重新启动mysql之前&#xff0c;都要删除这个文件夹 因为这个文件夹在后端执行一些我们看不到的…

pycharm打包python文件为exe文件(图文教程)

1.安装pyinstaller库 pip3 install pyinstaller 2.使用pyinstaller 打包文件 首先确保Terminal命令行中&#xff0c;你的路径和你的项目是同一个路径 我的项目就是放在golden_dev中的。 3.命令行内输入打包代码 pyinstaller -F -w gold_miner.py gold_miner.py 是我的项目…

HomePlug AV

目录 HomePlug AV的基本概念基本术语网络概念网络实例 HomePlug AV物理层&#xff08;PHY&#xff09;HomePlug AV OFDM收发器架构PHY的调制模式FC调制和ROBO调制物理层的特点OFDM频域/时域转换开窗/槽式OFDM信号和噪声PHY发送控制——信道自适应PHY帧格式&#xff08;Symbol&a…

微软邮箱被锁住,该如何解除限制?

ChatGPT账号是微软邮箱注册的&#xff0c;我们在登陆微软邮箱时&#xff0c;http://www.outlook.com&#xff0c;不需要开魔法工具&#xff0c;直接就可以登陆&#xff0c;否则会出现安全验证&#xff0c;限制登陆。 那么如果账号被锁&#xff0c;我们该如何解除限制呢&#x…

目标检测——监控下的汽车

一、重要性及意义 首先&#xff0c;车辆检测技术是保证视频监控系统正常运行的基础。通过监控摄像头实时获取的图像&#xff0c;可以自动检测出图像中的车辆&#xff0c;并进行车辆类型的分类和识别。这对于优化城市交通管理、实现智能交通系统具有重要意义。此外&#xff0c;…

【LeetCode热题100】51. N 皇后(回溯)

一.题目要求 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方…

渐进式图片解决前端在页面中使用大图,图片体积过大导致页面出现白屏现象

1、演示 可以看到&#xff0c;图片还在拼命加载的时候&#xff0c; 页面上就已经有内容了 2、什么渐进式图片 图片一开始是模糊的&#xff0c;然后逐渐的开始变的清晰。如果页面上有一些大图&#xff0c;如果直接扔给浏览器的话那么图片的传输时间就会比较长&#xff0c;用户就…

fastadmin学习08-查询数据渲染到前端

index.php查询&#xff0c;这个是前台的index.php public function index() {$slideImgs Db::name("slideimg")->where("status",,normal)->limit(5)->order(sort,desc)->select();$productList Db::name("product")->where(…

windows10 上安装 docker

windows 10 上安装 docker 官方目前给的方案是利用 Docker Desktop 来安装 docker 环境 一、安装前准备工作 1.1 检查系统要求 Windows 10 64 位&#xff1a;Home 或 Pro 2004&#xff08;内部版本 19041&#xff09;或更高版本&#xff0c;或者 Enterprise 或 Education 1…

每日一题————P5725 【深基4.习8】求三角形

题目&#xff1a; 题目乍一看非常的简单&#xff0c;属于初学者都会的问题——————————但是实际上呢&#xff0c;有一些小小的坑在里面。 就是三角形的打印。 平常我们在写代码的时候&#xff0c;遇到打印三角形的题&#xff0c;一般简简单单两个for循环搞定 #inclu…

【Clang+LLVM+honggfuzz学习】(二)honggfuzz的安装与试用

书接上篇【ClangLLVMhonggfuzz学习】&#xff08;一&#xff09;LLVM简介、安装和第一个Hello Pass 本篇介绍honggfuzz的安装与简单使用 本文架构&#xff0c;PS:可选择观看哦 前言git安装试用编写测试文件demo.c设置环境变量开始fuzzFuzz-ing疑问 前言 漏洞检测做毕设&#…

【leetcode】 c++ 数字全排列, test ok

1. 问题 2. 思路 3. 代码实现 #if 0 class Solution { private:vector<int> path; // 满足条件的一个结果 vector<vector<int>> res; // 结果集 void backtracking(vector<int> nums, vector<bool> used){// 若path的个数和nums个数相等&…

事件循环(2024 面试题)

答题大纲 先说基本知识点&#xff0c;宏任务、微任务有哪些说事件循环机制过程&#xff0c;边说边画图出来说async/await执行顺序注意&#xff0c;可以把 chrome 的优化&#xff0c;做法其实是违法了规范的&#xff0c;V8 团队的PR这些自信点说出来&#xff0c;显得你很好学&a…

Unsafe类详解

1. Unsafe 概念 Unsafe类位于sun.misc包下&#xff0c;它是java实现高并发的基础&#xff0c;通过它可以执行一些不安全的操作&#xff0c;如像C语言一样直接操作内存资源&#xff0c; 它提供的这些方法增强了java对底层资源的操作能力&#xff0c;但同时也增加了程序出错的风…