C语言实现通讯录项目

一、通讯录功能

        实现一个可以存放100个人的信息的通讯录(这里采用静态版本),每个人的信息有姓名、性别、年龄、电话、地址等。

        通讯录可以执行的操作有添加联系人信息、删除指定联系人、查找指定联系人信息、修改指定联系人信息、显示联系人信息、根据联系人的某些信息(年龄、姓名、电话等)对联系人进行排序等。

二、代码

1、测试文件(test.c)

#include "contact.h"
int main()
{int input = 0;Contact con;//创建一个通讯录对象,内部可以存放100个人的信息ConInit(&con);//初始化通讯录,一定不能放在循环内部do{int (*p[])(Contact*) = { Add, Del, Search, Modify, Show, Sort };menu();printf("请选择:");scanf("%d", &input);if (input >= 1 && input <= 6)p[input - 1](&con);else if (input == 0)printf("退出通讯录\n");elseprintf("输入错误,请重新输入0~6之间的整数\n");} while (input);return 0;
}

2、通讯录具体实现(contact.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("***** 0. exit                  *****\n");printf("************************************\n");
}//初始化通讯录
void ConInit(Contact* pc)
{assert(pc);pc->count = 0;memset(pc->data, 0, sizeof(pc->data));
}//查找指定联系人
int FindByName(Contact* pc, char name[])
{for (int i = 0; i < pc->count; i++)if (0 == strcmp(name, pc->data[i].name))return i;//找到了返回下标return -1;//没找到返回-1
}//打印联系人信息
void Print(Contact* pc, int i)
{printf("    %-10s  %-10s  %-10s  %-10s     %-10s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].phone,pc->data[i].address);
}//删除、查找、修改公共信息
int PubInfor(Contact* pc, int n)
{char name[NAME] = { 0 };const char* arr[] = {"", "", "删除", "查找", "修改"};//用2个空字符串占位int pos = 0;while (1){printf("请输入要%s联系人姓名:", (DEL == n) ? arr[DEL] : ((SEARCH == n) ? arr[SEARCH] : arr[MODIFY]));scanf("%s", name);pos = FindByName(pc, name);if (-1 == pos)printf("待%s联系人的信息不存在\n", (DEL == n) ? arr[DEL] : ((SEARCH == n) ? arr[SEARCH] : arr[MODIFY]));elsebreak;}return pos;
}//录入信息
void EnterInfor(Contact* pc, int x)
{int num = -1;const char* arr[] = { "姓名", "性别", "年龄", "电话", "地址" };char* pch[] = { pc->data[x].name, pc->data[x].sex, pc->data[x].age, pc->data[x].phone, pc->data[x].address };while (1){num++;printf("请输入%s:", arr[num]);scanf("%s", pch[num]);if (4 == num)break;}
}//添加联系人信息
void Add(Contact* pc)
{assert(pc && (pc->count <= CON));//通讯录满,不能增加,空指针不能增加EnterInfor(pc, pc->count);pc->count++;printf("添加成功\n");Show(pc);
}//删除指定联系人
void Del(Contact* pc)
{assert(pc && (pc->count != 0));//空通讯录不能删int pos = PubInfor(pc, DEL);for (int i = pos; i < pc->count - 1; i++)pc->data[i] = pc->data[i + 1];pc->count--;printf("删除成功\n");Show(pc);
}//查找指定联系人信息
void Search(Contact* pc)
{assert(pc && (pc->count != 0));int pos = PubInfor(pc, SEARCH);printf("该联系人的信息如下\n");printf("    %-10s  %-10s  %-10s  %-10s      %-10s\n", "姓名", "性别", "年龄", "电话", "地址");Print(pc, pos);
}//修改指定联系人信息
void Modify(Contact* pc)
{assert(pc && (pc->count != 0));int pos = PubInfor(pc, MODIFY);printf("该联系人的信息如下\n");printf("    %-10s  %-10s  %-10s  %-10s      %-10s\n", "姓名", "性别", "年龄", "电话", "地址");Print(pc, pos);printf("请输入修改后的信息\n");EnterInfor(pc, pos);printf("修改成功\n");Show(pc);
}//显示联系人信息
void Show(const Contact* pc)
{assert(pc);printf("                         通讯录联系人的信息如下                         \n");printf("    %-10s  %-10s  %-10s  %-10s      %-10s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < pc->count; i++)Print(pc, i);
}//qsort()函数姓名比较基准
int CmpByName(const void* s1, const void* s2)
{return strcmp(((People*)s1)->name, ((People*)s2)->name);
}//qsort()函数性别比较基准
int CmpBySex(const void* s1, const void* s2)
{return strcmp(((People*)s1)->sex, ((People*)s2)->sex);
}//qsort()函数年龄比较基准
int CmpByAge(const void* s1, const void* s2)
{return strcmp(((People*)s1)->age, ((People*)s2)->age);
}//qsort()函数电话比较基准
int CmpByPhone(const void* s1, const void* s2)
{return strcmp(((People*)s1)->phone, ((People*)s2)->phone);
}//qsort()函数地址比较基准
int CmpByAddress(const void* s1, const void* s2)
{return strcmp(((People*)s1)->address, ((People*)s2)->address);
}//根据联系人信息对联系人进行排序
void Sort(Contact* pc)
{assert(pc && (pc->count != 0));printf("*********************************\n");printf("***** 1. name      2. sex   *****\n");printf("***** 3. age       4. phone *****\n");printf("***** 5. address   0. exit  *****\n");printf("*********************************\n");int input = 0;do{int (*p[])(const void*, const void*) = { CmpByName, CmpBySex, CmpByAge, CmpByPhone, CmpByAddress };printf("请选择排序基准:");scanf("%d", &input);if (input >= 1 && input <= 5){qsort(pc->data, pc->count, sizeof(People), *(p)[input - 1]);break;}else if (0 == input)printf("退出排序\n");elseprintf("输入错误,请重新输入0~5之间的整数\n");} while (input);if (input != 0){const char* arr[] = { "姓名", "性别", "年龄", "电话", "地址" };printf("按照%s排序成功\n", arr[input - 1]);Show(pc);}
}

3、头文件(contact.h)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>#define NAME 20
#define SEX 5
#define AGE 3
#define PHONE 12
#define ADDRESS 30
#define CON 100enum CONTACT
{EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT
};typedef struct People
{char name[NAME];       //姓名char sex[SEX];         //性别char age[AGE];         //年龄char phone[PHONE];     //电话char address[ADDRESS]; //地址
}People;typedef struct Contact
{People data[CON];  //创建一个可以存储信息的结构体数组size_t count;      //count记录通讯录中的人员个数
}Contact;void menu();//菜单
void ConInit(Contact* pc);//初始化通讯录
int FindByName(Contact* pc, char name[]);//查找指定联系人
void Print(Contact* pc, int i);//打印联系人信息
int PubInfor(Contact* pc, int n);//删除、查找、修改公共信息
void EnterInfor(Contact* pc, int x);//录入信息
void Add(Contact* pc);//添加联系人信息
void Del(Contact* pc);//删除指定联系人
void Search(Contact* pc);//查找指定联系人信息
void Modify(Contact* pc);//修改指定联系人信息
void Show(const Contact* pc);//显示联系人信息
int CmpByName(const void* s1, const void* s2);//qsort()函数姓名比较基准
int CmpBySex(const void* s1, const void* s2);//qsort()函数性别比较基准
int CmpByAge(const void* s1, const void* s2);//qsort()函数年龄比较基准
int CmpByPhone(const void* s1, const void* s2);//qsort()函数电话比较基准
int CmpByAddress(const void* s1, const void* s2);//qsort()函数地址比较基准
void Sort(Contact* pc);//根据联系人信息对联系人进行排序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/70702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HO3D_v3(handposeX-json 格式)数据集-release >> DataBall

注意&#xff1a; 1)为了方便使用&#xff0c;按照 handposeX json 自定义格式存储 2)使用常见依赖库进行调用,降低数据集使用难度。 3)部分数据集获取请加入&#xff1a;DataBall-X数据球(free) 4)完整数据集获取请加入&#xff1a;DataBall-X数据球(vip) HO3D 数据集官方…

Java线程池入门04

1. 提交任务的两种方式 executorsubmit 2. executor executor位于Executor接口中 public interface Executor {void executor(Runnable command); }executor提交的是无返回值的任务 下面是一个具体的例子 package LearnThreadPool; import java.util.concurrent.ExecutorSe…

2025-02-26 学习记录--C/C++-C语言 整数格式说明符

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; C语言 整数格式说明符 【例如 】&#x1f380; &#xff1a;在 C 语言中&#xff0c;%ld 是 printf 或 scanf 等格式化输入输出函…

【QT 一 | 信号和槽】

Qt5基本模块 Qt Creator 中的快捷键 • 注释&#xff1a;ctrl / • 运⾏&#xff1a;ctrl R • 编译&#xff1a;ctrl B • 字体缩放&#xff1a;ctrl 鼠标滑轮 • 查找&#xff1a;ctrl F • 整行移动&#xff1a;ctrl shift ⬆/⬇ • 帮助⽂档&#xff1a;F1 • 自动…

集成学习方法之随机森林

随机森林是一种集成学习算法&#xff0c;它基于决策树模型&#xff0c;通过构建多个决策树并将它们的预测结果进行组合&#xff0c;以提高模型的准确性和稳定性。以下是随机森林的详细介绍&#xff1a; 原理 随机森林通过从原始训练数据中有放回地随机抽样&#xff0c;生成多…

react 中,使用antd layout布局中的sider 做sider的展开和收起功能

一 话不多说&#xff0c;先展示效果&#xff1a; 展开时&#xff1a; 收起时&#xff1a; 二、实现代码如下 react 文件 import React, {useState} from react; import {Layout} from antd; import styles from "./index.module.less"; // 这个是样式文件&#…

【Java 基础】-- Java 接口中的 @Public 和 @FunctionalInterface 注解详解

目录 Java 接口中的 Public 和 FunctionalInterface 注解详解 1. 概述 2. Public 注解的作用 3. Public 注解的使用 3.1 基本使用方式 3.2 应用于类和方法 4. FunctionalInterface 注解的作用 4.1 主要作用 4.2 FunctionalInterface 使用示例 4.3 允许默认方法 5. Pu…

go语言环境下载与配置(Windows)

下载 Go下载 - Go语言中文网 - Golang中文社区 建议在D盘中创建文件夹安装到 D 盘 &#xff0c;方便进行管理&#xff0c;然后进行傻瓜式安装。 安装 验证安装 go version 安装成功 配置环境变量 winE --> 右击此电脑 --> 选择属性 --> 高级系统设置 --> 点击…

nss刷题5(misc)

[HUBUCTF 2022 新生赛]最简单的misc 打开后是一张图片&#xff0c;没有其他东西&#xff0c;分离不出来&#xff0c;看看lsb&#xff0c;红绿蓝都是0&#xff0c;看到头是png&#xff0c;重新保存为png&#xff0c;得到一张二维码 扫码得到flag [羊城杯 2021]签到题 是个动图…

OkHttp、Retrofit、RxJava:一文讲清楚

一、okHttp的同步和异步请求 Call 是 OkHttp 的核心接口&#xff0c;代表一个已准备好执行的 HTTP 请求。它支持 同步 和 异步 两种模式&#xff1a; enqueue——>okHttp异步 OkHttpClient client new OkHttpClient();Request request new Request.Builder().url("…

Redis分布式缓存面试题

为什么使用分布式缓存&#xff1f; 1. 提升性能 降低延迟&#xff1a;将数据缓存在离应用更近的地方&#xff0c;减少数据访问时间。减轻数据库压力&#xff1a;缓存频繁访问的数据&#xff0c;减少对后端数据库的请求&#xff0c;提升系统响应速度。 2. 扩展性 水平扩展&a…

基于阿里云PAI平台快速部署DeepSeek大模型实战指南

一、DeepSeek大模型&#xff1a;企业级AI应用的新标杆 1.1 为什么选择DeepSeek&#xff1f; 近期&#xff0c;DeepSeek系列模型凭借其接近GPT-4的性能和开源策略&#xff0c;成为全球开发者关注的焦点。在多项国际评测中&#xff0c;DeepSeek-R1模型在推理能力、多语言支持和…

C++---了解STL

上节学习了模板&#xff0c;那么就得谈到C的标准模板库STL。 C98&#xff1a;以模板方式重写了C标准库&#xff0c;引入了STL(标准模板库)。 1.概念 STL(Standard template Libarary)标准模板库&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&am…

分享几款比较常用的接口测试工具

首先&#xff0c;什么是接口呢&#xff1f; 接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。 系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把数据库共享给你&#xff0c;他只能给你…

Qt layout

文章目录 Qt layout**关键机制****验证示例****常见误区****最佳实践****总结**关键点总结&#xff1a;示例代码说明&#xff1a;结论&#xff1a; Qt layout 在 Qt 中&#xff0c;当调用 widget->setLayout(layout) 时&#xff0c;layout 的父对象会被自动设置为该 widget…

flutter: table calendar笔记

pub dev&#xff1a;table_calendar 3.2.0 我来详细解释 TableCalendar 是如何根据不同的 CalendarFormat 来显示界面的。主要逻辑在 CalendarCore 中实现。 核心逻辑分为以下几个部分&#xff1a; 页面数量计算 - _getPageCount 方法根据不同格式计算总页数&#xff1a; in…

【C++】各个版本新的特性和改进

C 语言自从其诞生以来&#xff0c;经历了多个版本的更新&#xff0c;每个版本都引入了新的特性和改进&#xff0c;目的是提升语言的表达能力、性能、安全性以及开发效率。下面是各个主要版本&#xff08;从 C98 到 C20&#xff09;的一些关键特性。 C98 (1998年) ISO C 标准化…

C++模板与STL七日斩:从工业编程到高效数据管理(工业项目)

模板如何提升工业代码复用性 实战项目&#xff1a;创建通用【工业设备容器】模板类 类模板的定义与实例化模板参数默认值 #include <iostream> #include <string> using namespace std;template <typename T string> class IndustrialContainer { priva…

sh脚本把服务器B,服务器C目录的文件下载到服务器A目录,添加开机自启动并且一小时执行一次脚本

脚本逻辑 第一次会下载,第二次比较如果有就不下载 文件已存在&#xff1a; 如果目标目录中已经存在同名文件&#xff0c;rsync 会比较源文件和目标文件的大小和修改时间。 如果源文件和目标文件的大小和修改时间完全相同&#xff0c;rsync 会跳过该文件&#xff0c;不会重新下载…

云手机如何进行经纬度修改

云手机如何进行经纬度修改 云手机修改经纬度的方法因不同服务商和操作方式有所差异&#xff0c;以下是综合多个来源的常用方法及注意事项&#xff1a; 通过ADB命令注入GPS数据&#xff08;适用于技术用户&#xff09; 1.连接云手机 使用ADB工具连接云手机服务器&#xff0c;…