文章目录
- 🚩前言
- 🔊 项目需求
- 📚 项目知识点包含
- 🧩项目框架
- 📝框架拆解分析
- ✨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;
}