当前位置: 首页 > news >正文

通讯录程序

假设通讯录可以存放100个人的信息(人的信息:姓名、年龄、性别、地址、电话)

功能:1>增加联系人   2>删除指定联系人   3>查找指定联系人信息  4>修改指定联系人信息

           5>显示所有联系人信息  6>排序(姓名、年龄)

---------------------------------------------------------------------------------------------------------------------------------

根据前面三子棋等游戏,我们知道需要创建三个文件,test.c - 测试通讯录

  contact.c - 通讯录的实现     contact.h - 函数的声明

我们首先写出整体的代码(test.c):

#include "contact.h"void menu()
{printf("******************************************\n");printf("******      1. add       2. del     ******\n");printf("******      3. search    4. modify  ******\n");printf("******      5. show      0. exit    ******\n");printf("******    6.sortbyname   7.sortbyage******\n");printf("******************************************\n");
}
int main()
{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 0:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}}while(input);return 0;
}

第二步我们使用结构体类型来存放人的信息并声明所创建的通讯录(contact.h ):

#include <stdio.h>#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12//人的信息
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char addr[ADDR_MAX];char tele[TELE_MAX];
}PeoInfo;typedef struct Contact
{PeoInfo data[MAX];//存放人的信息int sz;//当前已经放的信息的个数
}Contact;

接下来创建通讯录及初始化通讯录(test.c):

//创建通讯录
Contact con;
//初始化通讯录
InitContact(&con);

初始化通讯录(contact.c):

void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data,0,sizeof(pc->data));
}

一、增加联系人函数

在Contact结构体内,PeoInfo类型的变量data存放人的信息(0,1,……),整型sz是当前已经存放的信息个数(0,1,……),那我们可以将sz作为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);printf("-------------------------------显示结果-----------------------------------\n");int i = 0;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);}printf("--------------------------------------------------------------------------\n");
}

三、删除指定联系人函数

想要找到指定删除的联系人,必须先知道他的名字,因此,我们在写该函数前,再写一个函数来确定姓名,能够找到该联系人姓名返回其下标,如果找不到该联系人就返回-1

int FindByName(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(ret == -1){printf("要删除的人不存在\n");return;}int i = 0;//删除for(i = 0;i < pc->sz-1; i++)//这里-1是因为当i=99时,i+1就是100,即当要将下标为100的第101个元素搬到下标为99的第100个元素,越界访问,所以要减去1{pc->data[i] = pc->data[i+1]}pc->sz--;//已经删除掉一个人的信息,那么总的个数就要减掉一个printf("删除成功\n");
}

四、查找指定联系人信息函数

想要查找指定联系人信息,一样需要先找到联系人的名字,一样用到FindByName函数

void SearchContact(const Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要查找的人的名字:>");scanf("%s",name);int ret = FindByName(pc,name);if(ret == -1){printf("要查找的人不存在\n");return;}//打印信息printf("-------------------------------查找结果-----------------------------------\n");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);printf("--------------------------------------------------------------------------\n");}

五、修改指定联系人信息函数

一样需要借助FindByName函数

void ModifyContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要修改的人的名字:>");scanf("%s",name);int ret = FindByName(pc,name);if(ret == -1){printf("要修改的人不存在\n");return;}//修改printf("请输入修改的名字:>");scanf("%s", pc->data[ret].name);printf("请输入修改的年龄:>");scanf("%d", &pc->data[ret].age);printf("请输入修改的性别:>");scanf("%s", pc->data[ret].sex);printf("请输入修改的地址:>");scanf("%s", pc->data[ret].addr);printf("请输入修改的电话:>");scanf("%s", pc->data[ret].tele);printf("修改成功\n");
}

六、排序函数

我们需要用到之前学到的qsort排序函数

6.1 根据姓名排序

int cmpbyname(const void* p1,const void* p2)
{assert(p1 && p2);return strcmp((PeoInfo*)p1)->name,((PeoInfo*)p2)->name);
}
void SortContactByName(Contact* pc)
{assert(pc);if(pc->data == 0){printf("通讯录为空,无需排序\n");return;}qsort(pc->data,pc->sz,sizeof(PeoInfo),cmpbyname);printf("排序成功\n");
}

6.2 根据年龄排序

int cmpbyage(const void* p1,const void* p2)
{assert(p1 && p2);return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}
void SortContactByAge(Contact* pc)
{assert(pc);if(pc->data == 0){printf("通讯录为空,无需排序\n");return;}qsort(pc->data,pc->sz,sizeof(PeoInfo),cmpbyage);printf("排序成功\n");
}

七、完整代码

contact.h#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12#define DEFAUT_ST 3
#define INC_SZ 2//人的信息
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char addr[ADDR_MAX];char tele[TELE_MAX];
}PeoInfo;typedef struct Contact
{PeoInfo data[MAX];//存放人的信息int sz;//当前已经放的信息的个数
}Contact;//初始化通讯录
void InitContact(Contact* pc);//增加联系人
void AddContact(Contact* pc);//显示通讯录中的信息
void ShowContact(const Contact* pc);//删除指定联系人
void DelContact(Contact* pc);//查找指定联系人
void SearchContact(const Contact* pc);//修改指定联系人
void ModifyContact(Contact* pc);//通过姓名排序
void SortContactByName(Contact* pc);//通过年龄排序
void SortContactByAge(Contact* pc);
test.c#include "contact.h"void menu()
{printf("******************************************\n");printf("******      1. add       2. del     ******\n");printf("******      3. search    4. modify  ******\n");printf("******      5. show      0. exit    ******\n");printf("******    6.sortbyname   7.sortbyage******\n");printf("******************************************\n");}
int main()
{int input = 0;int num = 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:SortContactByName(&con);break;case 7:SortContactByAge(&con);break;case 0:printf("˳ͨѶ¼\n");break;default:printf("ѡ\n");break;}} while (input);return 0;
}
contact.c#define _CRT_SECURE_NO_WARNINGS 1
#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);printf("-------------------------------显示结果-----------------------------------\n");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);}printf("--------------------------------------------------------------------------\n");}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++)//这里-1是因为当i=99时,i+1就是100,即当要将下标为100的第101个元素搬到下标为99的第100个元素,越界访问{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("-------------------------------查找结果-----------------------------------\n");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);printf("--------------------------------------------------------------------------\n");
}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");
}int cmpbyname(const void* p1,const void* p2)
{assert(p1 && p2);return strcmp((PeoInfo*)p1)->name,((PeoInfo*)p2)->name);
}
void SortContactByName(Contact* pc)
{assert(pc);if(pc->data == 0){printf("通讯录为空,无需排序\n");return;}qsort(pc->data,pc->sz,sizeof(PeoInfo),cmpbyname);printf("排序成功\n");
}int cmpbyage(const void* p1,const void* p2)
{assert(p1 && p2);return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}
void SortContactByAge(Contact* pc)
{assert(pc);if(pc->data == 0){printf("通讯录为空,无需排序\n");return;}qsort(pc->data,pc->sz,sizeof(PeoInfo),cmpbyage);printf("排序成功\n");
}

八、添加枚举类型

test.c 文件中,switch 函数内部,根据菜单选项,写为case 1,2……,这样有点难以看懂,例如,当 case 1 内的 AddContact 函数没有写时,如果忘记选项1是什么功能时,又得到回去看菜单,而添加一个枚举类型就可以避免这一操作,且枚举常量不赋值默认从0开始,依次增加1

test.c#include "contact.h"void menu()
{printf("******************************************\n");printf("******      1. add       2. del     ******\n");printf("******      3. search    4. modify  ******\n");printf("******      5. show      0. exit    ******\n");printf("******    6.sortbyname   7.sortbyage******\n");printf("******************************************\n");}enum Option
{EXIT, //0ADD,  //1DEL,  //2SEARCH,MODIFY,SHOW,sortbyname,sortbyage
};int main()
{int input = 0;int num = 0;//ͨ创建通讯录Contact con;//初始化通讯录InitContact(&con);do{menu();printf("ѡ:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case sortbyname:SortContactByName(&con);break;case sortbyage:SortContactByAge(&con);break;case EXIT:printf("˳ͨѶ¼\n");break;default:printf("ѡ\n");break;}} while (input);return 0;
}

相关文章:

  • 利用比较预言机处理模糊的偏好数据
  • Java Spring MVC -01
  • [Java实战]Spring Boot 3 整合 Apache Shiro(二十一)
  • 多模态融合【十九】——MRFS: Mutually Reinforcing Image Fusion and Segmentation
  • GOOSE 协议中MAC配置
  • CVE-2025-31258 macOS远程视图服务沙箱逃逸漏洞PoC已公开
  • JAVA研发+前后端分离,ZKmall开源商城B2C商城如何保障系统性能?
  • 使用scp命令拷贝hadoop100中文件到其他虚拟机中
  • 深度学习之优化器【从梯度下降到自适应学习率算法】(pytorch版)
  • C语言| extern的用法作用
  • TB67S109AFTG, TB67S109AFNG是一款采用PWM斩波器的两相双极步进电机驱动器内置有时钟输入解码器。采用BiCD工艺制造
  • java刷题基础知识
  • 如何通过 Windows 图形界面找到 WSL 主目录
  • 玩转ChatGPT:DeepSeek实战(统一所在地格式)
  • EMQX v5.0通过连接器和规则同步数据
  • STM32 内存
  • 网页常见水印实现方式
  • 牛客周赛96补题 D F
  • 机器学习第八讲:向量/矩阵 → 数据表格的数学表达,如Excel表格转数字阵列
  • 数据集-目标检测系列- 杨桃 数据集 Starfruit>> DataBall
  • 牛市早报|中方调整对美加征关税措施,五部门约谈外卖平台企业
  • 中国巴西民间推动建立经第三方验证的“森林友好型”牛肉供应链
  • 人民日报钟声:通过平等对话协商解决分歧的重要一步
  • 北京“准80后”干部兰天跨省份调任新疆生态环境厅副厅长
  • 上海国际电影节特设“今日亚洲”单元
  • 河南洛阳新安县煤渣倾倒耕地:多年难恢复,为何至今未解决?