目录
实战项目(通讯录)
功能
0.存放1000个好友的信息:名字,电话,性别,住址,年龄
1.增加好友的信息
2.删除指定名字的好友信息
3.查找好友信息
4.修改好友信息
5.排序
6.打印好友信息
1.列大纲
#include<stdio.h>
void menu()
{
printf("****************************************\n");
printf("****** 1.add 2.del ********\n");
printf("****** 3.search 4.modify ********\n");
printf("****** 5.sort 6.print ********\n");
printf("****** 0.exit ********\n");
printf("****************************************\n");
}
enum option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINTF
};
int main()
{
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
printf("增加函数\n");
break;
case DEL:
printf("删减函数\n");
break;
case SEARCH:
printf("查找函数\n");
break;
case MODIFY:
printf("修改函数\n");
break;
case SORT:
printf("排序函数\n");
break;
case PRINTF:
printf("打印函数\n");
break;
case EXIT:
printf("退出程序\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
2.实现增加函数和打印函数
增加函数增加到哪?首先要创建一个存放联系人的结构体
然后先实现两个函数看看效果
test.c(通讯录的测试)
#include"contact.h"
void menu()
{
printf("****************************************\n");
printf("****** 1.add 2.del ********\n");
printf("****** 3.search 4.modify ********\n");
printf("****** 5.sort 6.print ********\n");
printf("****** 0.exit ********\n");
printf("****************************************\n");
}
enum option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINTF
};
int main()
{
int input = 0;
//创建通讯录 info(信息)
contact con;
//初始化通讯录函数
init_contact(&con);
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
add_contact(&con);
break;
case DEL:
printf("删减函数\n");
break;
case SEARCH:
printf("查找函数\n");
break;
case MODIFY:
printf("修改函数\n");
break;
case SORT:
printf("排序函数\n");
break;
case PRINTF:
print_contact(&con);
break;
case EXIT:
printf("退出程序\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
contact.h(通讯录的各种声明)
#include<stdio.h>
#include<string.h>
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 20
#define MAX_ADDR 30
//类型的定义
typedef struct peoinfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}peoinfo;
//通讯录
typedef struct contact
{
peoinfo data[MAX];//存放添加进来的人的信息
int sz;//记录的是当前通讯录中有效信息的个数
}contact;
//初始化通讯录函数
void init_contact(contact* p);
//增加联系人函数
void add_contact(contact* p);
//打印联系人函数
void print_contact(const contact* p);
contact.c(通讯录函数的实现)
#include"contact.h"
//初始化通讯录函数
void init_contact(contact* p)
{
p->sz = 0;
memset(p->data, 0, sizeof(p->data));
}
//增加联系人函数
void add_contact(contact* p)
{
if (p->sz == MAX)
{
printf("通讯录已满,无法添加");
return;
}
printf("请输入要添加人的姓名:");
scanf("%s", p->data[p->sz].name);
printf("请输入要添加人的性别:");
scanf("%s", p->data[p->sz].sex);
printf("请输入要添加人的年龄:");
scanf("%d", &p->data[p->sz].age);//只用年龄不是数组,要取地址
printf("请输入要添加人的电话:");
scanf("%s", p->data[p->sz].tele);
printf("请输入要添加人的住址:");
scanf("%s", p->data[p->sz].addr);
p->sz++;
printf("添加成功\n");
}
//打印联系人函数
void print_contact(const contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法打印\n");
}
else
{
printf("%-10s %-10s %-10s %-15s %-10s\n", "姓名", "性别", "年龄", "电话", "住址");
for (int i = 0;i < p->sz;i++)
{
printf("%-10s %-10s %-10d %-15s %-10s\n",
p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].tele,
p->data[i].addr);
}
}
}
3.实现删除函数和查找函数
实现删除函数的时候发现需要用到查找函数的一部分,所以先写一个小的查找函数
test.c
#include"contact.h"
void menu()
{
printf("****************************************\n");
printf("****** 1.add 2.del ********\n");
printf("****** 3.search 4.modify ********\n");
printf("****** 5.sort 6.print ********\n");
printf("****** 0.exit ********\n");
printf("****************************************\n");
}
enum option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINTF
};
int main()
{
int input = 0;
//创建通讯录 info(信息)
contact con;
//初始化通讯录函数
init_contact(&con);
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
add_contact(&con);
break;
case DEL:
del_contact(&con);
break;
case SEARCH:
find_contact(&con);
break;
case MODIFY:
printf("修改函数\n");
break;
case SORT:
printf("排序函数\n");
break;
case PRINTF:
print_contact(&con);
break;
case EXIT:
printf("退出程序\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
contact.h
#include<stdio.h>
#include<string.h>
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 20
#define MAX_ADDR 30
//类型的定义
typedef struct peoinfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}peoinfo;
//通讯录
typedef struct contact
{
peoinfo data[MAX];//存放添加进来的人的信息
int sz;//记录的是当前通讯录中有效信息的个数
}contact;
//初始化通讯录函数
void init_contact(contact* p);
//增加联系人函数
void add_contact(contact* p);
//打印联系人函数
void print_contact(const contact* p);
//删除联系人函数
void del_contact(contact* p);
//查找联系人函数
void find_contact(const contact* p);
contact.c
#include"contact.h"
//初始化通讯录函数
void init_contact(contact* p)
{
p->sz = 0;
memset(p->data, 0, sizeof(p->data));
}
//增加联系人函数
void add_contact(contact* p)
{
if (p->sz == MAX)
{
printf("通讯录已满,无法添加");
return;
}
printf("请输入要添加人的姓名:");
scanf("%s", p->data[p->sz].name);
printf("请输入要添加人的性别:");
scanf("%s", p->data[p->sz].sex);
printf("请输入要添加人的年龄:");
scanf("%d", &p->data[p->sz].age);//只有年龄不是数组,要取地址,其它的数组名就是地址
printf("请输入要添加人的电话:");
scanf("%s", p->data[p->sz].tele);
printf("请输入要添加人的住址:");
scanf("%s", p->data[p->sz].addr);
p->sz++;
printf("添加成功\n");
}
//打印联系人函数
void print_contact(const contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法打印\n");
}
else
{ //负号是左对齐
printf("%-10s %-10s %-10s %-15s %-10s\n", "姓名", "性别", "年龄", "电话", "住址");
for (int i = 0;i < p->sz;i++)
{
printf("%-10s %-10s %-10d %-15s %-10s\n",
p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].tele,
p->data[i].addr);
}
}
}
//查找函数的一部分,且删除和修改联系人也要用到,只放在这就行,不用放在contact.h
static int find_by_name(contact* p, char name[])
{
for (int i = 0;i < p->sz;i++)
{
if (strcmp(p->data[i].name,name)==0)
{
return i;//找到了就返回下标
}
}
return -1;
}
//删除联系人函数
void del_contact(contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法删除\n");
}
else
{
char name[MAX_NAME] = { 0 };
printf("请输入要删除人的名字:");
scanf("%s", name);
int pos = find_by_name(p, name);
if (pos == -1)
{
printf("要删除的人不存在\n");
}
else
{
for (int i = pos;i < p->sz - 1;i++)//把找到的下标后面的全部往前挪
{
p->data[i] = p->data[i + 1];
}
p->sz--;//要删除的被覆盖,最后一个和倒数第二个内容一样,sz--就看不到最后一个了
//或者要删除的是最后一个,for循环不会进去sz--也看不到了
printf("删除成功\n");
}
}
}
//查找联系人函数
void find_contact(const contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法查找\n");
}
else
{
char name[MAX_NAME] = { 0 };
printf("请输入要查找人的名字:");
scanf("%s", name);
int pos = find_by_name(p, name);
if (pos == -1)
{
printf("要查找的人不存在\n");
}
else
{
printf("%-10s %-10s %-10s %-15s %-10s\n", "姓名", "性别", "年龄", "电话", "住址");
printf("%-10s %-10s %-10d %-15s %-10s\n",
p->data[pos].name,
p->data[pos].sex,
p->data[pos].age,
p->data[pos].tele,
p->data[pos].addr);
}
}
}
4.实现修改函数和排序函数
写到这发现很多函数都是差不多的,复制粘贴其他函数,改改中文就行
静态通讯录完整代码:
test.c
#include"contact.h"
void menu()
{
printf("****************************************\n");
printf("****** 1.add 2.del ********\n");
printf("****** 3.search 4.modify ********\n");
printf("****** 5.sort 6.print ********\n");
printf("****** 0.exit ********\n");
printf("****************************************\n");
}
enum option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINTF
};
int main()
{
int input = 0;
//创建通讯录 info(信息)
contact con;
//初始化通讯录函数
init_contact(&con);
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
add_contact(&con);
break;
case DEL:
del_contact(&con);
break;
case SEARCH:
find_contact(&con);
break;
case MODIFY:
modify_contact(&con);
break;
case SORT:
sort_contact(&con);
break;
case PRINTF:
print_contact(&con);
break;
case EXIT:
printf("退出程序\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
contact.h
#include<stdio.h>
#include<string.h>
#include<stdlib.h>//qsort
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 20
#define MAX_ADDR 30
//类型的定义
typedef struct peoinfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}peoinfo;
//通讯录
typedef struct contact
{
peoinfo data[MAX];//存放添加进来的人的信息
int sz;//记录的是当前通讯录中有效信息的个数
}contact;
//初始化通讯录函数
void init_contact(contact* p);
//增加联系人函数
void add_contact(contact* p);
//打印联系人函数
void print_contact(const contact* p);
//删除联系人函数
void del_contact(contact* p);
//查找联系人函数
void find_contact(const contact* p);
//修改联系人函数
void modify_contact(contact* p);
//排序联系人函数
void sort_contact(contact* p);
contact.c
#include"contact.h"
//初始化通讯录函数
void init_contact(contact* p)
{
p->sz = 0;
memset(p->data, 0, sizeof(p->data));
}
//增加联系人函数
void add_contact(contact* p)
{
if (p->sz == MAX)
{
printf("通讯录已满,无法添加");
return;
}
printf("请输入要添加人的姓名:");
scanf("%s", p->data[p->sz].name);
printf("请输入要添加人的性别:");
scanf("%s", p->data[p->sz].sex);
printf("请输入要添加人的年龄:");
scanf("%d", &p->data[p->sz].age);//只用年龄不是数组,要取地址
printf("请输入要添加人的电话:");
scanf("%s", p->data[p->sz].tele);
printf("请输入要添加人的住址:");
scanf("%s", p->data[p->sz].addr);
p->sz++;
printf("添加成功\n");
}
//打印联系人函数
void print_contact(const contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法打印\n");
}
else
{
printf("%-10s %-10s %-10s %-15s %-10s\n", "姓名", "性别", "年龄", "电话", "住址");
for (int i = 0;i < p->sz;i++)
{
printf("%-10s %-10s %-10d %-15s %-10s\n",
p->data[i].name,
p->data[i].sex,
p->data[i].age,
p->data[i].tele,
p->data[i].addr);
}
}
}
//查找函数的一部分,且删除和修改联系人也要用到,只放在这就行
static int find_by_name(contact* p, char name[])
{
for (int i = 0;i < p->sz;i++)
{
if (strcmp(p->data[i].name,name)==0)
{
return i;
}
}
return -1;
}
//删除联系人函数
void del_contact(contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法删除\n");
}
else
{
char name[MAX_NAME] = { 0 };
printf("请输入要删除人的名字:");
scanf("%s", name);
int pos = find_by_name(p, name);
if (pos == -1)
{
printf("要删除的人不存在\n");
}
else
{
for (int i = pos;i < p->sz - 1;i++)
{
p->data[i] = p->data[i + 1];
}
p->sz--;
printf("删除成功\n");
}
}
}
//查找联系人函数
void find_contact(const contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法查找\n");
}
else
{
char name[MAX_NAME] = { 0 };
printf("请输入要查找人的名字:");
scanf("%s", name);
int pos = find_by_name(p, name);
if (pos == -1)
{
printf("要查找的人不存在\n");
}
else
{
printf("%-10s %-10s %-10s %-15s %-10s\n", "姓名", "性别", "年龄", "电话", "住址");
printf("%-10s %-10s %-10d %-15s %-10s\n",
p->data[pos].name,
p->data[pos].sex,
p->data[pos].age,
p->data[pos].tele,
p->data[pos].addr);
}
}
}
//修改联系人函数
void modify_contact(contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法查找\n");
}
else
{
char name[MAX_NAME] = { 0 };
printf("请输入要修改人的姓名:");
scanf("%s", name);
int pos = find_by_name(p, name);
if (pos == -1)
{
printf("要修改的人不存在\n");
}
else
{
printf("以下是输入要修改人的新信息:\n");
printf("请输入姓名:");
scanf("%s", p->data[pos].name);
printf("请输入性别:");
scanf("%s", p->data[pos].sex);
printf("请输入年龄:");
scanf("%d", &p->data[pos].age);
printf("请输入电话:");
scanf("%s", p->data[pos].tele);
printf("请输入住址:");
scanf("%s", p->data[pos].addr);
printf("修改成功\n");
}
}
}
//排序联系人函数
int cmp(void* e1, void* e2)
{
return strcmp(((peoinfo*)e1)->name, ((peoinfo*)e2)->name);
}
void sort_contact(contact* p)
{
if (p->sz == 0)
{
printf("通讯录为空,无法排序\n");
}
else
{
qsort(p->data, p->sz, sizeof(peoinfo), cmp);
printf("按照姓名排序成功\n");
}
}
本篇完
实现修改函数和排序函数之后静态通讯录就完成了
静态通讯录的缺陷:
我们在一开始就定义了通讯录能存1000个人,开辟了1000个空间,很多没用到的空间都浪费了
编译器的警告:
警告C6262函数使用堆叠的 "88008" 字节。请考虑将一些数据移动到堆。
怎么达到想增加联系人的时候再开辟一些额外的空间呢?
这就要用到下一章的动态内存开辟了。(后面还会实现动态通讯录)
(穿越回来贴个链接)C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_GR C的博客-CSDN博客
本章完。