前言
通讯录作为通讯录地址的书本,当今的通讯录可以涵盖多项内容。在手机,电脑等电子设备中也拥有这种功能,它里面涵盖多种内容,如:姓名、年龄、性别、地址、电话等等,本文就用C语言带大家去实现静态通讯录。
同往期的扫雷、三子棋,这次同样是分成三个模块:
测试的逻辑——test.c
功能的实现——contact.h
函数的声明——contact.c
目录
一.功能实现
1.打印开始菜单
和三子棋扫雷一样,我们都需要有一个开始菜单,告诉使用者有那些功能,对于我们的通讯录来说,无非就是添加联系人、删除联系人、查找联系人、修改联系人等等,那和三子棋扫雷一样,我们先将这些制作到菜单当中,让使用者选择
编辑
void menu() { printf("*********************************\n"); printf("***** 1.add 2.del ****\n"); printf("***** 3.search 4.modify ****\n"); printf("***** 5.show 6.sort ****\n"); printf("***** 7.empty 0.exit ****\n"); printf("*********************************\n"); }
2.实现选择
选择选择也于扫雷三子棋大同小异,利用dowhile语句来实现多次循环,因为这次选择的功能很多,所以我们采用switch语句。
int input = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); switch(input) { case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6:; break; case 7: break; case 0: printf("退出通讯录\n"); break; default: printf("选择错误,请重新选择\n"); break; } } while (input);
3.创建结构体
我们要实现一个通讯录,那我们这些数据要放在哪里?这里就用到了我们的结构体,我们需要一个结构体,代表一个人的信息,名字,,年龄,性别,地址这些,那我们还需要确定的是,我们这个通讯录能存多少个人的信息,那我们就假设我们通讯里可以存放一百个人的,那这一百个人,我们去存放的时候怎么知道我们存了多少个人了信息了呢?那这里我们就可以在用一个结构体,里面放我们存放信息的结构体数组。
typedef struct People { char name[20]; int age; char sex[5]; char addr[30]; char tele[12]; }People; //静态版本 typedef struct Contact { People data[100];//存放人的信息 int sz;//当前已经存放的信息的个数 }Contact; //动态版本 typedef struct Contact { People* data;//指向存放人的信息的空间 int sz;//当前已经放的信息的个数 int capacity;//当前通讯录的最大容量 }Contact;
//创建通讯录 Contact con;
4.初始化通讯录
那有了这些东西,在没有初始化之前,这些变量和数组里面存放的东西都是未知的,那就需要我们去初始化数组,我们可以直接用第二个结构体类型定义一个变量然后等于0,全初始化成0,我们也可以用一个函数menset来进行我们的初始化,将我们存放信息的数组内的初始化成我们想要的数值。
void InitContact(Contact* pc)//初始化 { assert(pc); pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); //使用memeset函数将p->data所指向的空间中的数据初始化为0 //操作的空间大小为sizeof函数所计算出的p->data所指向空间的大小,即整个无联系人数据的结构体数组data所占的空间的大小 }
5.功能实现
(1)添加联系人
添加联系人,这个函数实现逻辑很简单,我们每次添加之前,先确定我们的通讯录是有位置的,所以我们可以先对sz进行一个判断,如果它等于100,就告诉我们通讯录已满,如果没有,就将下标为sz的位置替换成我们想要输入的信息,然后sz加加。
void AddContact(Contact* pc) { assert(pc); if (pc->sz == MAX) { printf("通讯录已满,无法添加\n"); return; } //增加一个人的信息 printf("请输入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:>"); scanf("%s", pc->data[pc->sz].sex); printf("请输入地址:>"); scanf("%s", pc->data[pc->sz].addr); printf("请输入电话:>"); scanf("%s", pc->data[pc->sz].tele); pc->sz++; }
(2)删除联系人
删除联系人,我们可以采用输入名字,然后删除的方式,所以我们可以输入一个名字,然后开始对比数组内的每一个名字,相等就进去,跳出循环,然后开始让后面的信息往前面覆盖,最后让sz减减,这里我们要注意,我们后续实现的内容很多都要用到我们的查找,那我们就可以将查找部分分装成一个函数,返回一个整数,如果找不到,就返回-1,找到了,返回此时的下标位置。
int FindByName(const Contact* pc, char name[]) { assert(pc); int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return i; } } return -1; } void DelContact(Contact* pc) { assert(pc); char name[NAME_MAX] = { 0 }; if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } //删除 //找到要删除的人 printf("请输入要删除的人的名字:>"); scanf("%s", name); int ret = FindByName(pc, name); if (-1 == ret) { printf("要删除的人不存在\n"); return; } int i = 0; //删除 for (i = ret; i < pc->sz - 1; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); }
(3)查找联系人
查找就和我们的删除思路大概一样了,同样调用我们的查找函数,找不到返回-1,告诉我们没有这个人,然后跳出函数,但是后面找到就与删除不一样了,我们将返回下标对应的内容打印出来,就找到了,这里找到联系人之后,信息打印在屏幕上,但是没有提示,对于我们来说可能就有点难确定哪个是哪个,所以这里我们加一个表头,对应每个信息。
void SearchContact(const Contact* pc) { assert(pc); char name[NAME_MAX] = { 0 }; printf("请输入要查找人的名字:>"); scanf("%s", name); int pos = FindByName(pc, name); if (-1 == pos) { printf("要查找的人不存在\n"); return; } //打印信息 printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话"); printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele); }
(4)修改联系人
修改也是用我们的查找函数,查找不到就告诉我们没有,然后跳出,查找到了就修改。
//修改联系人 void ModifyContact(Contact* pc) { assert(pc); char name[NAME_MAX] = { 0 }; printf("请输入要修改人的名字:>"); scanf("%s", name); int pos = FindByName(pc, name); if (-1 == pos) { printf("要修改的人不存在\n"); return; } printf("请输入名字:>"); scanf("%s", pc->data[pos].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pos].age)); printf("请输入性别:>"); scanf("%s", pc->data[pos].sex); printf("请输入地址:>"); scanf("%s", pc->data[pos].addr); printf("请输入电话:>"); scanf("%s", pc->data[pos].tele); printf("修改完成\n"); }
(5)显示所有联系人
我们要显示所有联系人,只用打印出我们数组的所有内容就可以,为了方便我们查看,也打印上表头。
//显示全部联系人 void ShowContact(const Contact* pc) { assert(pc); int i = 0; printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话"); for (i = 0; i < pc->sz; i++) { printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele); } }
(6)清空联系人
void ClearContact(Contact* pc)// 清空所有联系人 { pc->sz = 0; printf("已清空通讯录\n"); }
(7)排序联系人
排序,我们可以用qsort,进行排序,用名字来进行排序。
void sort_contact(Contact* pc)//以名字排序所有联系人 { int i = 0; int j = 0; for (i = 0; i < pc->sz; i++)//冒泡法排序 { for (j = 0; j < pc->sz - 1 - i; j++) { if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0) { People tmp = pc->data[j]; pc->data[j] = pc->data[j + 1]; pc->data[j + 1] = tmp; } } } }
二.完整代码
1.contact.h
#pragma once #include <stdio.h> #include <string.h> #include <assert.h> #include <stdlib.h> #define MAX 100 #define NAME_MAX 20 #define SEX_MAX 5 #define ADDR_MAX 30 #define TELE_MAX 12 #define DEFAULT_SZ 3 #define INC_SZ 2 //人的信息(姓名,年龄,性别,地址,电话) typedef struct People { char name[NAME_MAX]; int age; char sex[SEX_MAX ]; char addr[ADDR_MAX]; char tele[TELE_MAX]; }People; typedef struct Contact { People data[MAX];//存放人的信息 int sz;//当前已经存放的信息的个数 }Contact; //函数声明 //初始化通讯录 void InitContact(Contact* pc); //增加联系人 void AddContact(Contact* pc); //删除指定联系人 void DelContact(Contact* pc); //显示通讯录中的信息 void ShowContact(const Contact* pc); //查找指定联系人 void SearchContact(const Contact* pc); //修改指定联系人 void ModifyContact(Contact* pc); //排序 void sort_contact(Contact* pc); //清空联系人 void ClearContact(Contact* pc);
2.contact.c
#include "contact.h" //函数定义 void InitContact(Contact* pc)//初始化 { assert(pc); pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); } void AddContact(Contact* pc) { assert(pc); if (pc->sz == MAX) { printf("通讯录已满,无法添加\n"); return; } //增加一个人的信息 printf("请输入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:>"); scanf("%s", pc->data[pc->sz].sex); printf("请输入地址:>"); scanf("%s", pc->data[pc->sz].addr); printf("请输入电话:>"); scanf("%s", pc->data[pc->sz].tele); pc->sz++; } void ShowContact(const Contact* pc) { assert(pc); int i = 0; printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话"); for (i = 0; i < pc->sz; i++) { printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele); } } int FindByName(const Contact* pc, char name[]) { assert(pc); int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return i; } } return -1; } void DelContact(Contact* pc) { assert(pc); char name[NAME_MAX] = { 0 }; if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } //删除 //找到要删除的人 printf("请输入要删除的人的名字:>"); scanf("%s", name); int ret = FindByName(pc, name); if (-1 == ret) { printf("要删除的人不存在\n"); return; } int i = 0; //删除 for (i = ret; i < pc->sz - 1; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); } void SearchContact(const Contact* pc) { assert(pc); char name[NAME_MAX] = { 0 }; printf("请输入要查找人的名字:>"); scanf("%s", name); int pos = FindByName(pc, name); if (-1 == pos) { printf("要查找的人不存在\n"); return; } //打印信息 printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话"); printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele); } void ModifyContact(Contact* pc) { assert(pc); char name[NAME_MAX] = { 0 }; printf("请输入要修改人的名字:>"); scanf("%s", name); int pos = FindByName(pc, name); if (-1 == pos) { printf("要修改的人不存在\n"); return; } printf("请输入名字:>"); scanf("%s", pc->data[pos].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pos].age)); printf("请输入性别:>"); scanf("%s", pc->data[pos].sex); printf("请输入地址:>"); scanf("%s", pc->data[pos].addr); printf("请输入电话:>"); scanf("%s", pc->data[pos].tele); printf("修改完成\n"); } void sort_contact(Contact* pc)//以名字排序所有联系人 { int i = 0; int j = 0; for (i = 0; i < pc->sz; i++)//冒泡法排序 { for (j = 0; j < pc->sz - 1 - i; j++) { if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0) { People tmp = pc->data[j]; pc->data[j] = pc->data[j + 1]; pc->data[j + 1] = tmp; } } } } void ClearContact(Contact* pc)// 清空所有联系人 { pc->sz = 0; printf("已清空通讯录\n"); }
3.test.c
#include"contact.h" void menu() { printf("*********************************\n"); printf("***** 1.add 2.del ****\n"); printf("***** 3.search 4.modify ****\n"); printf("***** 5.show 6.sort ****\n"); printf("***** 7.empty 0.exit ****\n"); printf("*********************************\n"); } int main() { int input = 0; Contact con; InitContact(&con); do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: AddContact(&con); break; case 2: DelContact(&con); break; case 3: SearchContact(&con); break; case 4: ModifyContact(&con); break; case 5: ShowContact(&con); break; case 6: sort_contact(&con); break; case 7: ClearContact(&con); break; case 0: printf("退出通讯录\n"); break; default: printf("选择错误,请重新选择\n"); break; } } while (input); return 0; }
本篇文章就到此为止了,希望佬们多多支持!😘😘