作者: 热爱编程的小y
专栏:C语言基础
座右铭:彼方尚有荣光在
我们设计的初级通讯录要具备以下功能:
1. 新增联系人
2. 删除联系人
3. 查找联系人
4. 修改联系人
5. 显示所有联系人
6. 按名字排序所有联系人
我们暂且给这个通讯录以100的存储空间,即可以存放100个不同的联系人
对于初学者来说,通讯录算的上一个工程量较大的代码了,所以我们需要把代码分成一个个模块,便于后续编译与修改,模块型的代码还有个好处,就是可以像积木一样拼接到其他代码上。
我们一般创建三个文件,分别是:
测试通讯录:test.c
实现通讯录:contacts.h
函数的声明:contacts.c
最终呈现在vs上是这样的:
依据通讯录的功能,我们可以列出这样的菜单:
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;
}
效果如下:
我们声明一个结构体,把联系人信息全部放到这个结构体当中,并且用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));
}
完成了上述操作,接下来要做的就是对通讯录各种功能的具体实现了。
在增加联系人之前先要确保通讯录留有一定空间,
在一次输入各种信息之后我们让参数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;
}
同理,在删除联系人之前,也要先确保通讯录内至少存有一个联系人。
我们删除采用从后往前依次赋值的方法,如图所示:
假设下标为9的联系人是要删除的对象,我们一次把下标为10的联系人信息赋给9,下标为11的赋给10……以此类推,最终变成:
如图所示,最后一个元素其实已经不需要了,所以我们只需要把参数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;
}
同理,也要先确保通讯录内至少存有一个联系人。
我们通过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;
}
同理……不说了
修改就是建立在查找基础之上。代码前半部分基本相同,后半部分新增一串联系人信息即可。
如下:
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;
}
同……不知道第几次理
我们只需要通过循环语句依次打印即可
如下:
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);
}
}
我们通过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;
}
代码还有不完善的地方,欢迎老铁们在评论区交流指正,觉得本篇文章还有价值的,请三连支持一下~~