实战项目(通讯录)
功能
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" 字节。请考虑将一些数据移动到堆。
怎么达到想增加联系人的时候再开辟一些额外的空间呢?
这就要用到下一章的动态内存开辟了。(后面还会实现动态通讯录)
本章完。