C语言:通讯录管理系统的实现

如何来实现通信录呢?

人的信息包括:名字+年龄+性别+电话+地址,等来表示

想要实现的功能:

1、默认存放100个人的信息

2、增加联系人信息

3、删除指定联系人信息

4、查找联系人信息

5、修改联系人信息

6、对联系人信息排序

7、显示联系人

想要实现通讯录管理系统 需要多个文件:

test.c                测试功能

contact.c          通讯录相关的实现

contact.h          通讯录相关的声明

接下来我们就来依次看这几个文件,首先对 test.c 文件搭建基本框架 :

#include"contact.h"void menu()
{printf("**************************************************\n");printf("--------------欢迎进入通讯录管理系统--------------\n");printf("**************************************************\n");printf("*************    1.增加联系人信息   **************\n");printf("*************    2.删除联系人信息   **************\n");printf("*************    3.查找联系人信息   **************\n");printf("*************    4.修改联系人信息   **************\n");printf("*************    5.排序联系人信息   **************\n");printf("*************    6.显示联系人信息   **************\n");printf("*************     0.退出管理系统    **************\n");printf("**************************************************\n");
}
int main()
{int input = 0;//PeoInfo data[100];//存放100个人的信息,但是当我们进行增删查改一系列操作时,data里的实际有效元素,信息人的个数不断发生变化,需要变量记录一下
//int count = 0;//用来记录通讯录里面联系人有多少,可以封装成一个结构体Contact con;//通讯录//初始化通讯录,可以用大括号初始化,之所以写函数来初始化,是为了让代码封装位模块的形式,另一方面是因为初始化的内容有些不能通过大括号来初始化InintContact(&con);//传址调用,1、节省空间,提高效率2、函数内部可以直接操作con的内容do{menu();printf("请选择:>\n");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");}} while (input);return 0;
}

接下来我们在 Contact.h 文件中进行类型的声明:

#include<stdio.h>
#include<string.h>
//类型的声明
typedef struct PeoInfo
{char name[20];int age;char sex[10];char tel[12];char addr[30];
}PeoInfo;
typedef struct Contact
{PeoInfo data[100];int count;
}Contact;

函数的实现在 Contact.c 文件中实现,首先我们应该对通讯录初始化,再分别实现各个函数的功能

#include"contact.h"
void InitContact(Contact* pc)
{pc->count = 0;memset(pc->data, 0, sizeof(pc->data));//memset内存设置函数:将指向内存块的字节设置为指定值,当然也可以通过循环来解决但较为麻烦
}

 我们来看第一个函数如何实现(增加联系人信息):

#include"Contact.h"
void AddContact(Contact* pc)
{if (pc->data == MAX){printf("通讯录已满,无法进行添加操作\n");return;}//未满,进行添加操作printf("请输入名字:>");//如果data里面没有数据,count就为0,可以作为下标,count为1时说明里面有1个数据,下标为1scanf("%s", pc->data[pc->count].name);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->count].age));printf("请输入性别:>");scanf("%s", pc->data[pc->count].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->count].tel);printf("请输入地址:>");scanf("%s", pc->data[pc->count].addr);pc->count++;printf("增加成功\n");
}
void ShowContact(const Contact* pc)
{int i = 0;printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");//\t表示的是水平制表符的意思,为了美观空出来,-表示左对齐的意思for (i = 0; i < pc->count; i++){printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tel, pc->data[i].addr);}
}

注意: 在这里我们之所以写了显示联系人信息的函数是因为,我们可以在增加联系人信息后,把联系人信息打印出来,以此来判断增加信息是否有误

然后我们再来实现删除联系人信息的函数操作:

 static int FindbyName(Contact* pc,char name[])//只能在这个Contact.c文件中使用
{int i = 0;for (i = 0; i < pc->count; i++){if (strcmp(pc->data[i].name,name)==0){return i;}}return -1;
}
void DelContact(Contact* pc)
{int i = 0;//我们可以按照名字来删除,当然也可以按照其他的来删除char name[MAX_NAME] = { 0 };//删除联系人的前提是数据不为空,所以我们应该先判断一下if (pc->count == 0){printf("通讯录为空,无法删除\n");return;}printf("请输入将要删除联系人姓名:>");scanf("%s", name);//删除联系人分两步,先查找是否存在该联系人,若存在才可删除//1、查找int ret=FindbyName(pc, name);//因为查找联系人、删除、修改、都要查找,所以封装一个函数,若找到返回下标,反之返回-1if (ret == -1){printf("该联系人不存在\n");return;}//2、删除,可以把后面的元素往前覆盖即可for (i = ret; i < pc->count-1; i++){pc->data[i] = pc->data[i + 1];}pc->count--;printf("删除成功\n");//也可以用memove来删除:memmove(&(pc->data[ret]), &(pc->data[ret + 1]), (pc->count - ret) * (sizeof(Contact)));但必须保证通讯录中联系人信息是连续的
}

Contact.c 中实现查找联系人的信息:

void SearchContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入将要查找联系人姓名:>");scanf("%s", name);int ret = FindbyName(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}else{printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tel, pc->data[ret].addr);}
}

修改联系人信息:

void ModifyContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入将要修改联系人姓名:>");scanf("%s", name);int ret = FindbyName(pc, name);if (ret == -1){char name[MAX_NAME] = { 0 };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].tel);printf("请输入地址:>");scanf("%s", pc->data[ret].addr);printf("修改成功\n");
}

对联系人信息排序:

int cmp_by_name(const char* e1, const char* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{//假如按照名字排序,快排qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

现在把代码总结到一起的话:

//contact.h文件

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TEL 12
#define MAX_ADDR 30
//类型的声明
typedef struct PeoInfo
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char tel[MAX_TEL];
    char addr[MAX_ADDR];
}PeoInfo;
typedef struct Contact
{
    PeoInfo data[MAX];
    int count;
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人信息
void AddContact(Contact* pc);
//显示联系人信息
void ShowContact(const Contact* pc);
//删除联系人信息
void DelContact(Contact* pc);
//查找联系人信息
void SearchContact(Contact* pc);
//修改联系人信息
void ModifyContact(Contact* pc);
//排序联系人信息
void SortContact(Contact* pc); 

//test.c文件

#include"contact.h"

void menu()
{
    printf("**************************************************\n");
    printf("--------------欢迎进入通讯录管理系统--------------\n");
    printf("**************************************************\n");
    printf("*************    1.增加联系人信息   **************\n");
    printf("*************    2.删除联系人信息   **************\n");
    printf("*************    3.查找联系人信息   **************\n");
    printf("*************    4.修改联系人信息   **************\n");
    printf("*************    5.排序联系人信息   **************\n");
    printf("*************    6.显示联系人信息   **************\n");
    printf("*************     0.退出管理系统    **************\n");
    printf("**************************************************\n");
}
int main()
{
    int input = 0;
    //PeoInfo data[100];//存放100个人的信息,但是当我们进行增删查改一系列操作时,data里的实际有效元素,信息人的个数不断发生变化,需要变量记录一下
    //int count = 0;//用来记录通讯录里面联系人有多少,可以封装成一个结构体
    Contact con;//通讯录
    //初始化通讯录,可以用大括号初始化,之所以写函数来初始化,是为了让代码封装位模块的形式,另一方面是因为初始化的内容有些不能通过大括号来初始化
    InitContact(&con);//传址调用,1、节省空间,提高效率2、函数内部可以直接操作con的内容
    do
    {
        menu();
        printf("请选择:>\n");
        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:
            SortContact(&con);
            break;
        case 6:
            ShowContact(&con);
            break;
        case 0:
            printf("退出管理系统\n");
            break;
        default:
            printf("选择错误请重新选择\n");
            break;
        }
    } while (input);
    return 0;
}

//contact.c文件

#include"contact.h"
void InitContact(Contact* pc)
{
    pc->count = 0;
    memset(pc->data, 0, sizeof(pc->data));//memset内存设置函数:将指向内存块的字节设置为指定值,当然也可以通过循环来解决但较为麻烦
}
 static int FindbyName(Contact* pc,char name[])
{
    int i = 0;
    for (i = 0; i < pc->count; i++)
    {
        if (strcmp(pc->data[i].name,name)==0)
        {
            return i;
        }
    }
    return -1;
}
void AddContact(Contact* pc)
{
    if (pc->data == MAX)
    {
        printf("通讯录已满,无法进行添加操作\n");
        return;
    }
    //未满,进行添加操作
    printf("请输入名字:>");//如果data里面没有数据,count就为0,可以作为下标,count为1时说明里面有1个数据,下标为1
    scanf("%s", pc->data[pc->count].name);
    printf("请输入年龄:>");
    scanf("%d", &(pc->data[pc->count].age));
    printf("请输入性别:>");
    scanf("%s", pc->data[pc->count].sex);
    printf("请输入电话:>");
    scanf("%s", pc->data[pc->count].tel);
    printf("请输入地址:>");
    scanf("%s", pc->data[pc->count].addr);
    pc->count++;
    printf("增加成功\n");
}
void ShowContact(const Contact* pc)
{
    int i = 0;
    printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
    for (i = 0; i < pc->count; i++)
    {
        printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tel, pc->data[i].addr);
    }
}
void DelContact(Contact* pc)
{
    int i = 0;
    //我们可以按照名字来删除,当然也可以按照其他的来删除
    char name[MAX_NAME] = { 0 };//删除联系人的前提是数据不为空,所以我们应该先判断一下
    if (pc->count == 0)
    {
        printf("通讯录为空,无法删除\n");
        return;
    }
    printf("请输入将要删除联系人姓名:>");
    scanf("%s", name);
    //删除联系人分两步,先查找是否存在该联系人,若存在才可删除
    //1、查找
    int ret=FindbyName(pc, name);//因为查找联系人、删除、修改、都要查找,所以封装一个函数,若找到返回下标,反之返回-1
    if (ret == -1)
    {
        printf("该联系人不存在\n");
        return;
    }
    //2、删除,可以把后面的元素往前覆盖即可
    for (i = ret; i < pc->count-1; i++)
    {
        pc->data[i] = pc->data[i + 1];
    }
    pc->count--;
    printf("删除成功\n");
    //也可以用memove来删除:memmove(&(pc->data[ret]), &(pc->data[ret + 1]), (pc->count - ret) * (sizeof(Contact)));但必须保证通讯录中联系人信息是连续的
}
void SearchContact(Contact* pc)
{
    char name[MAX_NAME] = { 0 };
    printf("请输入将要查找联系人姓名:>");
    scanf("%s", name);
    int ret = FindbyName(pc, name);
    if (ret == -1)
    {
        printf("要查找的人不存在\n");
        return;
    }
    else
    {
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
        printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tel, pc->data[ret].addr);
    }
}
void ModifyContact(Contact* pc)
{
    char name[MAX_NAME] = { 0 };
    printf("请输入将要修改联系人姓名:>");
    scanf("%s", name);
    int ret = FindbyName(pc, name);
    if (ret == -1)
    {
        char name[MAX_NAME] = { 0 };
        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].tel);
    printf("请输入地址:>");
    scanf("%s", pc->data[ret].addr);
    printf("修改成功\n");
}
int cmp_by_name(const char* e1, const char* e2)
{
    return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
    //假如按照名字排序,快排
    qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
    printf("排序成功\n");
}

 

 

 

 

 

 

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

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

相关文章

C语言 | Leetcode C语言题解之第110题平衡二叉树

题目&#xff1a; 题解&#xff1a; int height(struct TreeNode* root) {if (root NULL) {return 0;}int leftHeight height(root->left);int rightHeight height(root->right);if (leftHeight -1 || rightHeight -1 || fabs(leftHeight - rightHeight) > 1) {…

Fortran: select type

Fortran: select type 实现类似C的template函数功能 module M_reduceuse mpi_f08interface reducemodule procedure reduce_scalar,reduce_arrayend interface reducecontains!!https://docs.open-mpi.org/en/v5.0.x/man-openmpi/man3/MPI_Reduce.3.htmlsubroutine reduce_ar…

Android硬件渲染环境初始化

Android硬件渲染环境初始化 一.硬件加速渲染的开启1.ThreadedRenderer的初始化2.RenderProxy的创建 二.RenderProxy中组件的初始化1.RenderThread的创建2.CanvasContext的创建3.DrawFrameTask的初始化 三.RenderThread的启动1.RenderThread中组件的初始化2.RenderThread中任务的…

arXiv AI 综述列表(2024.05.20~2024.05.24)

公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 每周末更新&#xff0c;完整版进群获取。 Q 群在群文件&#xff0c;VX 群每周末更新。 目录 1. Beyond Traditional Single Object Tracking: A …

基于yolov2深度学习网络的昆虫检测算法matlab仿真,并输出昆虫数量和大小判决

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022A 3.部分核心程序 .......................................................... for i 1:12 % 遍历结…

播兔短剧模板:图鸟UI在前端短剧平台中的应用与实践

一、引言 随着移动互联网的快速发展&#xff0c;短剧平台因其短小精悍、内容丰富的特点&#xff0c;逐渐成为用户休闲娱乐的新宠。为了满足短剧平台对前端技术的需求&#xff0c;图鸟播兔短剧模板应运而生。该模板基于图鸟UI进行开发&#xff0c;采用纯前端技术&#xff0c;支…

layui-左侧递归菜单-js实现

完整代码 两种下拉风格 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title>…

【C语言回顾】文件操作

前言1. 文件打开模式2. 示例代码2.1 打开和关闭文件2.2 读写文件2.3 二进制文件操作 结语 #include<GUIQU.h> int main { 上期回顾: 【C语言回顾】动态内存管理 个人主页&#xff1a;C_GUIQU 专栏&#xff1a;【C语言学习】 return 一键三连; } 前言 各位小伙伴大家好&…

美国空军出版物:网络空间作战

这份文件是《AIR FORCE DOCTRINE PUBLICATION 3-12: CYBERSPACE OPERATIONS》&#xff0c;即美国空军教义出版物3-12&#xff0c;关于网络空间作战。 该文件详细阐述了美国空军在网络空间领域的组织、规划、执行、评估以及相关的政策、角色和责任。 以下是其核心内容的概述&a…

搜索引擎索引是什么

搜索引擎索引是搜索引擎中的关键组件&#xff0c;用于存储和管理网页、文档、图片等信息&#xff0c;并提供快速的检索功能。索引包括索引基础、单词词典、倒排列表、建立索引、动态索引、索引更新策略、查询处理、多字段索引、短语查询和分布式索引。 索引基础&#xff1a;索…

特定情况下docker run --restart=always重启失效的情况

特定情况下解决cicd中docker run --restartalways重启失效的情况_c 执行exit后 restartalways失效-CSDN博客

分享:怎么才能保证大数据查询的准确性?

随着大数据应用到金融风控领域&#xff0c;大数据越来越重要了&#xff0c;很多朋友在查大数据的时候都会遇到一个问题&#xff0c;那就是自己查询的大数据什么信息都没有&#xff0c;要么就是很少&#xff0c;这是什么原因呢?要怎么才能保证大数据查询的准确性呢?下面小编就…

给JTextArea添加右键菜单

给JTextArea添加右键菜单 package jTextarea;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import jav…

Java进阶学习笔记3——static修饰成员方法

成员方法的分类&#xff1a; 类方法&#xff1a;有static修饰的成员方法&#xff0c;属于类&#xff1a; 成员方法&#xff1a;无static修饰的成员方法&#xff0c;属于对象。 Student类&#xff1a; package cn.ensource.d2_staticmethod;public class Student {double scor…

双拼打字,可以尝试这个练习平台

本文将介绍由本人开发的双拼练习平台打字侠&#xff0c;以及一些对新手学习双拼的建议。课程一共233课&#xff0c;共分为两大部分&#xff1a; 韵母键位&#xff0c;主要练习双拼中韵母对应的键盘键位&#xff0c;同时提供可视化的键盘指法示意图。 实战练习&#xff0c;同时…

Selenium常用命令(python版)

日升时奋斗&#xff0c;日落时自省 目录 1、Selenium 2、常见问题 1、Selenium 安装Python和配置环境没有涉及 注&#xff1a;如有侵权&#xff0c;立即删除 首先安装selenium包&#xff0c;安装方式很简单 pip install selenium 注:我这里已经安装好了&#xff0c;所以…

怎么一键消除路人?教你三个消除方法

怎么一键消除路人&#xff1f;在数字时代&#xff0c;摄影已成为我们记录生活、表达情感的重要方式。然而&#xff0c;完美的照片背后往往隐藏着一些不那么完美的元素——比如那些不经意间闯入镜头的路人。他们或许只是匆匆过客&#xff0c;但却足以破坏你精心构图的美好瞬间。…

分割文本文件

分割一个.txt文件&#xff0c;可以选择在命令行中使用split指令&#xff0c;或者编写一段脚本进行操作。以下是一个简单的Python脚本来分割文本文件&#xff1a; def split_file(file, lines):# Open source filewith open(file, r) as source:count 0atEOF Falsewhile not …

shell笔记脚本3

执行脚本文件demo2.sh, 观察打印VAR4效果 执行脚本文件后, 在交互式Shell环境打印VAR4, 观察打印VAR4效果 结论 全局变量在当前Shell环境与子Shell环境中可用, 父Shell环境中不可用 小结 自定义变量的分类 自定义局部变量: 就是在一个脚本文件内部使用 var_namevalue 自…

128天的创意之旅:从初心到成就,我的博客创作纪念日回顾

文章目录 &#x1f680;机缘&#xff1a;初心的种子——回望创作之旅的启航&#x1f308;收获&#xff1a;成长的果实——128天创作之旅的宝贵馈赠❤️日常&#xff1a;创作与生活的交织&#x1f44a;成就&#xff1a;代码的艺术&#x1f6b2;憧憬&#xff1a;未来的蓝图 &…