🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:初出茅庐C语言 ?? 学习格言:眼泪终究流不成海洋,人总要不断成长! 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同成长! 🌹
一、通讯录
1.演示效果
2.完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <assert.h>
#include <stdio.h>
#define MAX 30
#define NAME 20
#define TEL 20
#define ADR 30
struct PopInfo {
char name[NAME];
int age;
char tel[TEL];
char adr[ADR];
};
struct Contact {
struct PopInfo data[MAX];
int sz;
};
void InitContact(struct Contact* con)
{
assert(con);
memset(con->data, 0, MAX * sizeof(struct PopInfo));
con->sz = 0;
}
void AddContact(struct Contact* con)
{
assert(con);
printf("请输入姓名:");
scanf("%s", con->data[con->sz].name);
printf("请输入年龄:");
scanf("%d", &(con->data[con->sz].age));
printf("请输入手机号:");
scanf("%s", con->data[con->sz].tel);
printf("请输入住址:");
scanf("%s", con->data[con->sz].adr);
con->sz++;
printf("成功添加联系人!\n");
}
void ShowContact(struct Contact* con)
{
int i = 0;
printf("%-20s\t%-20s\t%-20s\t%-20s\t\n", "姓名", "年龄", "手机号", "住址");
for (i = 0; i < con->sz; i++)
{
printf("%-20s\t%-20d\t%-20s\t%-20s\t\n", con->data[i].name, con->data[i].age, con->data[i].tel, con->data[i].adr);
}
}
int Find(struct Contact* con)
{
char name[20];
scanf("%s", name);
int i = 0;
for (i = 0; i < con->sz; i++)
{
if (strcmp(con->data[i].name, name) == 0)
{
return i;
break;
}
}
return -1;
}
void DelContact(struct Contact* con)
{
assert(con);
printf("请输入你要删除的联系人姓名:");
int i = Find(con);
if (i == -1)
{
printf("未找到你要删除的联系人\n");
}
else
{
int j = 0;
for (j = i; j <= con->sz; j++)
{
con->data[j] = con->data[j + 1];
}
con->sz--;
printf("删除成功!\n");
}
}
void ModContact(struct Contact* con)
{
assert(con);
printf("请输入你要修改的联系人姓名:");
int i = Find(con);
if (i == -1)
{
printf("未找到你要删除的联系人\n");
}
else
{
printf("请输入姓名:");
scanf("%s", con->data[i].name);
printf("请输入年龄:");
scanf("%d", &(con->data[i].age));
printf("请输入手机号:");
scanf("%s", con->data[i].tel);
printf("请输入住址:");
scanf("%s", con->data[i].adr);
printf("成功修改联系人信息!\n");
}
}
void SearchContact(struct Contact* con)
{
assert(con);
printf("请输入你要查找的联系人姓名:");
int i = Find(con);
if (i == -1)
{
printf("没有找到你要查找的联系人!\n");
}
else
{
printf("%-20s\t%-20s\t%-20s\t%-20s\t\n", "姓名", "年龄", "手机号", "住址");
printf("%-20s\t%-20d\t%-20s\t%-20s\t\n", con->data[i].name, con->data[i].age, con->data[i].tel, con->data[i].adr);
}
}
int cmp_name(const void* e1, const void* e2)
{
return strcmp(((struct PopInfo*)e1)->name, ((struct PopInfo*)e2)->name);
}
void Sort_name_Contact(struct Contact* con)
{
qsort(con->data, con->sz, sizeof(struct PopInfo), cmp_name);
printf("排序成功\n");
}
void ClearContact(struct Contact* con)
{
char str[10];
while (1)
{
printf("确定清空通讯录吗?(yes/no):");
scanf("%s", str);
if (strcmp(str, "yes") == 0)
{
con->sz = 0;
printf("已清空通讯录!\n");
break;
}
else if (strcmp(str, "no") == 0)
{
printf("已取消!\n");
break;
}
else
printf("输入错误,请重新输入!\n");
}
}
enum um {
Exit,
Add,
Del,
Mod,
Search,
Sort_name,
Show,
Clear
};
void menu()
{
printf("*******************************\n");
printf("*** 1.添加联系人信息 **\n");
printf("*** 2.删除指定联系人信息 **\n");
printf("*** 3.修改联系人信息 **\n");
printf("*** 4.查找联系人信息 **\n");
printf("*** 5.按照姓氏对联系人排序 **\n");
printf("*** 6.显示联系人信息 **\n");
printf("*** 7.清空所有联系人信息 **\n");
printf("*** 0.退出程序 **\n");
}
int main()
{
int input = 0;
struct Contact con;
InitContact(&con);
do {
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case Add:
AddContact(&con);
break;
case Del:
DelContact(&con);
break;
case Mod:
ModContact(&con);
break;
case Search:
SearchContact(&con);
break;
case Sort_name:
Sort_name_Contact(&con);
break;
case Show:
ShowContact(&con);
break;
case Clear:
ClearContact(&con);
break;
case Exit:
printf("退出程序\n");
break;
default:
printf("输入错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
二、代码解析
1.宏定义及结构体声明
#include <assert.h>
#include <stdio.h>
#define MAX 30
#define NAME 20
#define TEL 20
#define ADR 30
struct PopInfo {
char name[NAME];
int age;
char tel[TEL];
char adr[ADR];
};
struct Contact {
struct PopInfo data[MAX];
int sz;
};
定义struct PopInfo 结构体用来保存联系人的信息,再定义struct Contact ,用来保存多个联系人的信息以及记录所存储联系人个数。
2.主菜单函数
void menu()
{
printf("*******************************\n");
printf("*** 1.添加联系人信息 **\n");
printf("*** 2.删除指定联系人信息 **\n");
printf("*** 3.修改联系人信息 **\n");
printf("*** 4.查找联系人信息 **\n");
printf("*** 5.按照姓氏对联系人排序 **\n");
printf("*** 6.显示联系人信息 **\n");
printf("*** 7.清空所有联系人信息 **\n");
printf("*** 0.退出程序 **\n");
}
3.主函数
int main()
{
enum um {
Exit,
Add,
Del,
Mod,
Search,
Sort_name,
Show,
Clear
};
int input = 0;
struct Contact con;
InitContact(&con);
do {
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case Add:
AddContact(&con);
break;
case Del:
DelContact(&con);
break;
case Mod:
ModContact(&con);
break;
case Search:
SearchContact(&con);
break;
case Sort_name:
Sort_name_Contact(&con);
break;
case Show:
ShowContact(&con);
break;
case Clear:
ClearContact(&con);
break;
case Exit:
printf("退出程序\n");
break;
default:
printf("输入错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
4.查找函数
int Find(struct Contact* con)
{
char name[20];
scanf("%s", name);
int i = 0;
for (i = 0; i < con->sz; i++)
{
if (strcmp(con->data[i].name, name) == 0)
{
return i;
break;
}
}
return -1;
}
根据姓名查找存放联系人信息的数组下标,用于后来查找、删除、修改联系人信息时使用。
5.初始化联系人信息
void InitContact(struct Contact* con)
{
assert(con);
memset(con->data, 0, MAX * sizeof(struct PopInfo));
con->sz = 0;
}
assert(con); 是判断指针con 是否为空,判断memset(con->data, 0, MAX * sizeof(struct PopInfo)) 是将结构体struct Contact 中struct PopInfo 类型的数组data 置为0。con->sz = 0; 是将所记录的联系人个数置为0。
6.添加联系人信息
void AddContact(struct Contact* con)
{
assert(con);
printf("请输入姓名:");
scanf("%s", con->data[con->sz].name);
printf("请输入年龄:");
scanf("%d", &(con->data[con->sz].age));
printf("请输入手机号:");
scanf("%s", con->data[con->sz].tel);
printf("请输入住址:");
scanf("%s", con->data[con->sz].adr);
con->sz++;
printf("成功添加联系人!\n");
}
注意在输入年龄的时候因为年龄是int 类型,要用& 符号取出地址,再进行赋值。
7.显示所有联系人信息
void ShowContact(struct Contact* con)
{
int i = 0;
printf("%-20s\t%-20s\t%-20s\t%-20s\t\n", "姓名", "年龄", "手机号", "住址");
for (i = 0; i < con->sz; i++)
{
printf("%-20s\t%-20d\t%-20s\t%-20s\t\n", con->data[i].name, con->data[i].age, con->data[i].tel, con->data[i].adr);
}
}
printf("%-20s\t%-20s\t%-20s\t%-20s\t\n", "姓名", "年龄", "手机号", "住址") 中的%-20s\t%-20s\t%-20s\t%-20s\t\n 是为了让打印联系人信息的时候更加直观,%-20s\t%-20s\t%-20s\t%-20s\t\n 中的- 是为了让其左对齐,把- 去掉可以是右对齐。
8.删除指定联系人信息
void DelContact(struct Contact* con)
{
assert(con);
printf("请输入你要删除的联系人姓名:");
int i = Find(con);
if (i == -1)
{
printf("未找到你要删除的联系人\n");
}
else
{
int j = 0;
for (j = i; j <= con->sz; j++)
{
con->data[j] = con->data[j + 1];
}
con->sz--;
printf("删除成功!\n");
}
}
代码中注释部分可以在不调用 Find 函数时删除联系人信息,在成功删除联系人信息后,要将存放联系人个数的变量进行修改。
9.修改联系人信息
void ModContact(struct Contact* con)
{
assert(con);
printf("请输入你要修改的联系人姓名:");
int i = Find(con);
if (i == -1)
{
printf("未找到你要删除的联系人\n");
}
else
{
printf("请输入姓名:");
scanf("%s", con->data[i].name);
printf("请输入年龄:");
scanf("%d", &(con->data[i].age));
printf("请输入手机号:");
scanf("%s", con->data[i].tel);
printf("请输入住址:");
scanf("%s", con->data[i].adr);
printf("成功修改联系人信息!\n");
}
}
10.查找指定联系人
void SearchContact(struct Contact* con)
{
assert(con);
printf("请输入你要查找的联系人姓名:");
int i = Find(con);
if (i == -1)
{
printf("没有找到你要查找的联系人!\n");
}
else
{
printf("%-20s\t%-20s\t%-20s\t%-20s\t\n", "姓名", "年龄", "手机号", "住址");
printf("%-20s\t%-20d\t%-20s\t%-20s\t\n", con->data[i].name, con->data[i].age, con->data[i].tel, con->data[i].adr);
}
}
11.按照姓氏对联系人信息排序
int cmp_name(const void* e1, const void* e2)
{
return strcmp(((struct PopInfo*)e1)->name, ((struct PopInfo*)e2)->name);
}
void Sort_name_Contact(struct Contact* con)
{
qsort(con->data, con->sz, sizeof(struct PopInfo), cmp_name);
printf("排序成功\n");
}
使用 qsort 函数对其进行排序。
12.清空所有联系人信息
void ClearContact(struct Contact* con)
{
char str[10];
while (1)
{
printf("确定清空通讯录吗?(yes/no):");
scanf("%s", str);
if (strcmp(str, "yes") == 0)
{
con->sz = 0;
printf("已清空通讯录!\n");
break;
}
else if (strcmp(str, "no") == 0)
{
printf("已取消!\n");
break;
}
else
printf("输入错误,请重新输入!\n");
}
}
|