小张刚学习完结构体,枚举,联合相关的知识,实践实践,写一个通讯录呗!
通讯录的功能
1.通讯录可存放100的信息
2.信息的内容姓名,性别,年龄,电话,地址
3.支持增加联系人
4.支持删除联系人
5.支持查找联系人
6.支持修改联系人
7.支持排序联系人
8.打印数据
文件类型
test.c(测试通讯录相关功能)
contanct.c(通讯录功能的实现)
contanct.h(声明)
一个人信息在结构体中定义
struct peoinfo {
char name[20];姓名
char sex[5];性别
int age;年龄
char tel[12];电话
char addr[20];};地址
为了方便代码的可读性,我们在宏里面定义每个字符串数组的长度,修改如下
struct peoinfo {
char name[MAX_NAME];姓名
char sex[MAX_SEX];性别
int age;年龄
char tel[MAX_TEL];电话
char addr[MAX_ADDR];地址};
宏定义如下
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TEL 12
#define MAX_ADDR 20
#define MAX 1000
通讯录用结构体
typedef struct pp{
struct peoinfo arr[MAX];
int sz;}pp;
用typedef将通讯录结构体类型重命名为pp,方便操作
菜单函数menu
void menu() { printf("#######################################\n"); printf("#********* 1.add ***************#\n"); printf("#********* 2.del ***************#\n"); printf("#********* 3.search ***************#\n"); printf("#********* 4.modify ***************#\n"); printf("#********* 5.sort ***************#\n"); printf("#********* 6.print ****************#\n"); printf("########## 0.exit ################\n"); }
选择功能函数test()
void test() {pp pro;//定义一个通讯录 Initcontanct(&pro);//通讯录初始化,具体在下面 int input; do { menu(); scanf_s("%d", &input); switch (input) { case 1: Addcontanct(&pro); break; case 2: Delcontanct(&pro); break; case 3: findcontanct(&pro); break; case 4: modifycontanct(&pro); break; case 5: Sortcontanct(&pro); break; case 6: Printcontanct(&pro); break; case 7: break; case 0: printf("退出通讯录\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); }
switch语句中的case1,2,3,4不好对应功能,为了提高代码可读性,我们可以定义一个枚举类型
enum opion
{
EXIT,//他的值为0,下面依次1,2,3,4,5,6
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
};
test()函数修改
void test() {pp pro; Initcontanct(&pro); int input; do { menu(); scanf_s("%d", &input); switch (input) { case ADD: Addcontanct(&pro); break; case DEL: Delcontanct(&pro); break; case SEARCH: findcontanct(&pro); break; case MODIFY: modifycontanct(&pro); break; case SORT: Sortcontanct(&pro); break; case PRINT: Printcontanct(&pro); break; case EXIT: printf("退出通讯录\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); }
初始化通讯录函数
作用:将sz初始化为0,将struct peoinfo arr[]初始化为0,防止初始化为随机值,memset函数可以将从哪个地址开始多少个字节置为你想置的数,第一个参数是从哪个地址开始重置,第二个参数是置为什么,第三个参数是置多少个字节,memset头文件stdlib.h
void Initcontanct(pp*p) { p->sz = 0; memset(p->arr, 0, sizeof(p->arr)); }
结构体指针p接收通讯录的地址&pro
添加联系人
void Addcontanct(pp* p) { if (p->sz == 1000) { printf("通讯录已经存满\n"); return; } printf("请输入姓名\n"); scanf("%s",p->arr[p->sz].name); printf("请输入性别\n"); scanf("%s",p->arr[p->sz].sex); printf("请输入年龄\n"); scanf("%d",&(p->arr[p->sz].age)); printf("请输入电话\n"); scanf("%s",p->arr[p->sz].tel); printf("请输入地址\n"); scanf("%s",p->arr[p->sz].addr); p->sz++; printf("录入成功\n"); }
注意年龄不是数组,scanf的时候必须加&取地址符,每次添加1个,p->sz+1;如果==1000,表示已经存满,return直接跳出,不再进行添加过程
打印数据函数
void Printcontanct(pp* p) { int i = 0; printf("******************************************************\n"); printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名","性别","年龄","电话","地址"); printf("******************************************************\n"); for (i = 0; i < p->sz; i++) { printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr); printf("******************************************************\n"); } }
注意:为了能打印更加美观,打印采用左对齐,打印*的每行为了将用户分开,更好看一点,循环遍历通讯录每个成员,将其打印,每个用户打印完了,记得换行
删除联系人
void Delcontanct(pp* p) { char name[MAX_NAME]; printf("请输入要删除朋友的名字\n"); scanf("%s",name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); for (int j = k; j < p->sz - 1; j++) { p->arr[j] = p->arr[j + 1]; } p->sz--; printf("删除成功\n"); } }
查找函数find()
int find(pp* p, char name[]) { int i = 0; for (int i = 0; i < p->sz; i++) { if (!strcmp(p->arr[i].name, name)) return i; } return -1; }
注意查找函数的功能是遍历通讯录,如果有此人,返回这个人数组的下标,如果没有此人,返回-1;使用strcmp比较函数记得头文件string.h,删除一个人,输入要删除的那个人的名字,将输入名字的数组地址和通讯录的地址传给find()函数,调用find()函数遍历通讯录,如果没有此人,find()函数返回-1;打印查无此人,否则用k接收其要删除用户的下标,将k下标的用户删除,然后将后面的依次向前挪,删除一个,对应的p->sz- -
查找联系人
void findcontanct(pp* p) { char name[MAX_NAME]; if (p->sz == 0) { printf("通讯录为空\n"); return; } printf("请输入要查找朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); printf("******************************************************\n"); printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址"); printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr); printf("******************************************************\n"); } }
注意:查找基本和删除类似,输入名字后,需要调用find函数查找对应名字的下标,返回-1;表示没找到,如果返回了下标将这个下标对应的信息打印出来
修改联系人信息
void modifycontanct(pp* p) { char name[MAX_NAME]; printf("请输入修改朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); printf("请输入要修改朋友的信息\n"); printf("修改性别->"); scanf("%s", p->arr[k].sex); printf("修改年龄->"); scanf("%d", &(p->arr[k].age)); printf("修改电话->"); scanf("%s", p->arr[k].tel); printf("修改地址->"); scanf("%s", p->arr[k].addr); printf("修改成功\n"); } }
注意修改联系人信息还是需要find()函数查找联系人名字,find()函数返回其下标,修改的时候,直接对下标对应的用户进行操作,年龄不是数组,scanf需要加&取地址符
排序联系人(年龄排序)
void Sortcontanct(pp* p) { int i = 0; for (int i = 0; i < p->sz-1; i++) { for (int j = 0; j < p->sz - i-1; j++) { if (p->arr[j].age > p->arr[j + 1].age) { int tmp = p->arr[j].age; p->arr[j].age = p->arr[j + 1].age; p->arr[j + 1].age = tmp; char name[MAX_NAME]; strcpy(name, p->arr[j].name); strcpy(p->arr[j].name, p->arr[j+1].name); strcpy(p->arr[j + 1].name, name); char sex[MAX_SEX]; strcpy(sex, p->arr[j].sex); strcpy(p->arr[j].sex, p->arr[j + 1].sex); strcpy(p->arr[j + 1].sex, sex); char tel[MAX_TEL]; strcpy(tel, p->arr[j].tel); strcpy(p->arr[j].tel, p->arr[j + 1].tel); strcpy(p->arr[j + 1].tel, tel); char addr[MAX_ADDR]; strcpy(addr, p->arr[j].addr); strcpy(p->arr[j].addr, p->arr[j + 1].addr); strcpy(p->arr[j + 1].addr, tel); } } } printf("按年龄排序成功,快去打印吧\n"); }
注意利用冒泡排序按年龄从小到大排序,将年龄交换的同时,需要将两个人的名字,性别,电话,住址也进行交换,字符串数组,我们采用strcpy,strcpy头文件string.h,交换的思想也是用到了三个数交换的灵感
但是我的上一篇讲的是qsort排序,我们也可以用qsort进行排序,
拒绝屎山代码
修改:排序联系人
int int_cmp_age(const void* p1, const void* p2)//按年龄比较 { return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age; } void Sortcontanct(pp* p) { qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age); printf("按年龄排序成功,快去打印吧\n"); }
整体代码展示
contanct.h
#pragma once #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <string.h> #include <stdlib.h> #define MAX_NAME 20 #define MAX_SEX 6 #define MAX_TEL 12 #define MAX_ADDR 20 #define MAX 1000 enum opion { EXIT, ADD, DEL, SEARCH, MODIFY, SORT, PRINT }; typedef struct peoinfo { char name[MAX_NAME]; char sex[MAX_SEX]; int age; char tel[MAX_TEL]; char addr[MAX_ADDR]; }peoinfo; typedef struct pp{ struct peoinfo arr[MAX]; int sz; }pp; void Initcontanct(pp*p); void Addcontanct(pp* p); void Printcontanct(pp* p); void Delcontanct(pp* p); void findcontanct(pp* p); void modifycontanct(pp* p); void Sortcontanct(pp* p);
contanct.c
#include"contanct.h" void Initcontanct(pp*p) { p->sz = 0; memset(p->arr, 0, sizeof(p->arr)); } void Addcontanct(pp* p) { if (p->sz == 1000) { printf("通讯录已经存满\n"); return; } printf("请输入姓名\n"); scanf("%s",p->arr[p->sz].name); printf("请输入性别\n"); scanf("%s",p->arr[p->sz].sex); printf("请输入年龄\n"); scanf("%d",&(p->arr[p->sz].age)); printf("请输入电话\n"); scanf("%s",p->arr[p->sz].tel); printf("请输入地址\n"); scanf("%s",p->arr[p->sz].addr); p->sz++; printf("录入成功\n"); } void Printcontanct(pp* p) { int i = 0; printf("******************************************************\n"); printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名","性别","年龄","电话","地址"); printf("******************************************************\n"); for (i = 0; i < p->sz; i++) { printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr); printf("******************************************************\n"); } } int find(pp* p, char name[]) { int i = 0; for (int i = 0; i < p->sz; i++) { if (!strcmp(p->arr[i].name, name)) return i; } return -1; } void Delcontanct(pp* p) { char name[MAX_NAME]; printf("请输入要删除朋友的名字\n"); scanf("%s",name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); for (int j = k; j < p->sz - 1; j++) { p->arr[j] = p->arr[j + 1]; } p->sz--; printf("删除成功\n"); } } void findcontanct(pp* p) { char name[MAX_NAME]; if (p->sz == 0) { printf("通讯录为空\n"); return; } printf("请输入要查找朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); printf("******************************************************\n"); printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址"); printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr); printf("******************************************************\n"); } } void modifycontanct(pp* p) { char name[MAX_NAME]; printf("请输入修改朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); printf("请输入要修改朋友的信息\n"); printf("修改性别->"); scanf("%s", p->arr[k].sex); printf("修改年龄->"); scanf("%d", &(p->arr[k].age)); printf("修改电话->"); scanf("%s", p->arr[k].tel); printf("修改地址->"); scanf("%s", p->arr[k].addr); printf("修改成功\n"); } } int int_cmp_age(const void* p1, const void* p2)//按年龄比较 { return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age; } void Sortcontanct(pp* p) { qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age); printf("按年龄排序成功,快去打印吧\n"); }
test.c
#include"contanct.h" void menu() { printf("#######################################\n"); printf("#********* 1.add ***************#\n"); printf("#********* 2.del ***************#\n"); printf("#********* 3.search ***************#\n"); printf("#********* 4.modify ***************#\n"); printf("#********* 5.sort ***************#\n"); printf("#********* 6.print ****************#\n"); printf("########## 0.exit ################\n"); } void test() {pp pro; Initcontanct(&pro); int input; do { menu(); scanf_s("%d", &input); switch (input) { case ADD: Addcontanct(&pro); break; case DEL: Delcontanct(&pro); break; case SEARCH: findcontanct(&pro); break; case MODIFY: modifycontanct(&pro); break; case SORT: Sortcontanct(&pro); break; case PRINT: Printcontanct(&pro); break; case EXIT: printf("退出通讯录\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } void main() { test(); }
结果展示
存在的问题大家可以指出,后面会和大家分享动态通讯录,大家多多支持,还有就是我访问终于破2000了哈哈哈哈哈
彩蛋
今天分享就到这里,下一篇见









