IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 实践 C语言进阶通讯录设计 -> 正文阅读

[C++知识库]实践 C语言进阶通讯录设计

通讯录的实现

文件目录

image-20220209223228247

需求分析

1. 存放1000个好友的信息
	信息内容包括:姓名、电话、性别、住址、年龄
2. 增加好友信息
3. 删除指定好友的信息
4. 查找好友信息
5. 修改好友信息
6. 打印好友信息
7. 排序

流程控制

//枚举类型
//作用:增加代码的可读性
enum Option
{
    EXIT,// 0
    ADD,//1
    DEL,//2
    SEARCH,//3
    MODIFY,//4 - 改
    SORT,//5
    PRINT//6
};
int main()
{
    int input = 0;
    //功能选择
    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 SORT:
                //有需要的话写
                break;
            case PRINT:
                //打印通讯录
                PrintContact(&con);
                break;
            case EXIT:
                printf("退出通讯录\n");
                break;
            default:
                printf("选择错误,重新选择\n");
                break;
        }
    } while (input);
    return 0;
}

具体功能实现

联系人结构体

typedef struct PeoInfo {
    //姓名
    char name[MAX_NAME];
    //性别
    char sex[MAX_SEX];
    //年龄
    int age;
    //电话
    char tele[MAX_TELE];
    //住址
    char addr[MAX_ADDR];
} PeoInfo;//直接重命名。

通讯录结构体

//将人员信息和当前通讯录大小封装在一起
typedef struct Contact
{
	PeoInfo data[MAX];//存放添加进来的人的信息
	int sz;//记录的是当前通讯录中已经有的元素个数
}Contact;

初始化通讯录

void InitContact(Contact* pc)
{
	pc->sz = 0;//设置通讯录最初只有0个元素
	//memset(); 内存设置  将所有的空间初始化为0
	memset(pc->data, 0, sizeof(pc->data));
}

添加联系人

void AddContact(Contact* pc)
{
    //通讯录满了的问题
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;//直接结束
	}
	//增加一个人的信息  在pc->data[MAX]中的sz下标处直接添加,添加完成后将sz加一。
	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].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);
	//添加完成后将sz加一
	pc->sz++;
    //打印添加情况
	printf("增加成功\n");
}

打印通讯录内容

void PrintContact(const Contact* pc)
{
    //通讯录为空情况和不为空的情况
    if(pc->sz == 0) printf("通讯录为空\n");
    else{
        int i = 0;
        //打印标题
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
        //打印信息
        for (i = 0; i < pc->sz; i++)
        {
            //打印一个人的信息
            printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
                   pc->data[i].name,
                   pc->data[i].age,
                   pc->data[i].sex,
                   pc->data[i].tele,
                   pc->data[i].addr);
        }
    }
}

通过姓名查找联系人

这个不是功能,但是是删除和查找人信息都要使用的功能,所以封装成函数。

但是由于这个函数只在这个文件中使用,所以在前面加上static相对更加安全。

static int FindByName(const Contact *pc, char name[]) {
    int i = 0;
    for (i = 0; i < pc->sz; i++) {
        //字符串之间的比较时用的strcmp
        if (strcmp(pc->data[i].name, name) == 0) {
            //如果找到返回下标找不到返回-1;
            return i;
        }
    }

    return -1;//找不到
}

删除指定的联系人

方法一:将后面的元素逐一向前移动,再将通讯录大小sz减一。

方法二:将最后一个数据放在要删除的位置上,再将通讯录大小s减一。

void DelContact(Contact* pc)
{
    char name[MAX_NAME] = {0};
    //通讯录为空,无法进行删除的情况
    if (pc->sz == 0)
    {
        printf("通讯录为空,无需删除\n");
        return;
    }
    //进行删除前的准备
    printf("请输入要删除人的名字:>");
    scanf("%s", name);

    //1. 查找要删除的人
    //有/没有
    int pos = FindByName(pc, name);
    if (pos == -1)
    {
        printf("要删除的人不存在\n");
        return;
    }
    //2. 删除
    //从要删除的位置开始逐一向前移动
    int i = 0;
    for (i = pos; i < pc->sz-1; i++)
    {
        pc->data[i] = pc->data[i + 1];
    }
    pc->sz--;
    printf("删除成功\n");
}

查找指定人的信息

void SearchContact(Contact *pc) {
    //存储要查找人的信息
    char name[MAX_NAME] = {0};
    printf("请输入要查找人的名字:>");
    scanf("%s", name);
    //查找
    int pos = FindByName(pc, name);
    //要查找人不存在
    if (pos == -1) {
        printf("要查找的人不存在\n");
        return;
        //可以查找到 打印被查找人的信息
    } else {
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
        //打印数据
        printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
               pc->data[pos].name,
               pc->data[pos].age,
               pc->data[pos].sex,
               pc->data[pos].tele,
               pc->data[pos].addr);
    }
}

修改指定联系人信息

void ModifyContact(Contact *pc) {
    char name[MAX_NAME] = {0};
    printf("请输入要修改人的名字:>");
    scanf("%s", name);

    int pos = FindByName(pc, name);
    if (pos == -1) {
        printf("要修改的人不存在\n");
        return;
    } else {
        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].tele);
        printf("请输入地址:>");
        scanf("%s", pc->data[pos].addr);

        printf("修改成功\n");
    }
}

版本升级

直接申请1000空间比较浪费,我们可以使用动态内存分配。

初始化和内存的销毁。

在每次都重新建联系人的信息不够方便可以将内容进行持久化。存在硬盘中。

void InitContact(Contact *pc) {
    pc->data = (PeoInfo *) malloc(DEFAULT_SZ * sizeof(PeoInfo));
    if (pc->data == NULL) {
        perror("InitContact");
        return;
    }
    pc->sz = 0;//初始化后默认是0
    pc->capacity = DEFAULT_SZ;

    //加载文件
    LoadContact(pc);
}

void DestoryContact(Contact *pc) {
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->capacity = 0;
}


void SaveContact(Contact *pc) {
    FILE *pf = fopen("contact.dat", "w");
    if (pf == NULL) {
        perror("SaveContact");
        return;
    }
    //写文件
    int i = 0;
    for (i = 0; i < pc->sz; i++) {
        fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
    }

    //关闭文件
    fclose(pf);
    pf = NULL;
}

void LoadContact(Contact *pc) {
    FILE *pf = fopen("contact.dat", "r");
    if (pf == NULL) {
        perror("LoadContact");
        return;
    }
    //读文件
    PeoInfo tmp = {0};
    while (fread(&tmp, sizeof(PeoInfo), 1, pf)) {
        //是否需要增容
        CheckCapacity(pc);
        pc->data[pc->sz] = tmp;
        pc->sz++;
    }

    //关闭文件
    fclose(pf);
    pf = NULL;
}

void CheckCapacity(Contact *pc) {
    if (pc->sz == pc->capacity) {
        PeoInfo *ptr = (PeoInfo *) realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
        if (ptr != NULL) {
            pc->data = ptr;
            pc->capacity += INC_SZ;
            printf("增容成功\n");
        } else {
            perror("AddContact");
            printf("增加联系人失败\n");
            return;
        }
    }
}

//动态版本- 增加联系人
void AddContact(Contact *pc) {
    //考虑增容
    CheckCapacity(pc);
    //增加一个人的信息
    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].tele);
    printf("请输入地址:>");
    scanf("%s", pc->data[pc->sz].addr);

    pc->sz++;
    printf("增加成功\n");
}

最终文件

main.c

//通讯录-静态版本
//1.通讯录中能够存放1000个人的信息
//每个人的信息:
//名字+年龄+性别+电话+地址
//2. 增加人的信息
//3. 删除指定人的信息
//4. 修改指定人的信息
//5. 查找指定人的信息
//6. 排序通讯录的信息
//版本2:
//动态增长的版本
//1>通讯录初始化后,能存放3个人的信息
//2>当我们空间的存放满的时候,我们增加2个信息
//3+2+2+2+...
//

//
//版本3
//当通讯录退出的时候,把信息写到文件
//当通讯录初始化的时候,加载文件的信息到通讯录中
//


#include "contact.h"

void menu()
{
    printf("**************************************\n");
    printf("*********  1. add    2. del   ********\n");
    printf("*********  3. search 4. modify********\n");
    printf("*********  5. sort   6. print ********\n");
    printf("*********  0. exit            ********\n");
    printf("**************************************\n");
}
//枚举类型
//作用:增加代码的可读性
enum Option
{
    EXIT,// 0
    ADD,//1
    DEL,//2
    SEARCH,//3
    MODIFY,//4 - 改
    SORT,//5
    PRINT//6
};

int main()
{
    int input = 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 SORT:
                //自己完善
                break;
            case PRINT:
                PrintContact(&con);
                break;
            case EXIT:
                //保存信息到文件
                SaveContact(&con);
                //销毁通讯录
                DestoryContact(&con);
                printf("退出通讯录\n");
                break;
            default:
                printf("选择错误,重新选择\n");
                break;
        }
    } while (input);
    return 0;
}

contact.h

//
// Created by Tian baby on 2022/2/9.
//

#ifndef CONTACT_CONTACT_H
#define CONTACT_CONTACT_H
#pragma once


#include <string.h>
#include <stdio.h>
#include <stdlib.h>

//定义人员信息结构体时使用的常量数字
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TELE 12
#define MAX_ADDR 30

#define MAX 1000

#define DEFAULT_SZ 3
#define INC_SZ 2

//好友信息的结构体
typedef struct PeoInfo {
    //姓名
    char name[MAX_NAME];
    //性别
    char sex[MAX_SEX];
    //年龄
    int age;
    //电话
    char tele[MAX_TELE];
    //住址
    char addr[MAX_ADDR];
} PeoInfo;//直接重命名。

//通讯录-静态版本
// //将人员信息和当前通讯录大小封装在一起
// typedef struct Contact
// {
//     PeoInfo data[MAX];//存放添加进来的人的信息
//     int sz;//记录的是当前通讯录中已经有的元素个数
// }Contact;

//通讯录-动态版本
typedef struct Contact {
    PeoInfo *data;//指向动态申请的空间,用来存放联系人的信息
    int sz;//记录的是当前通讯录中有效信息的个数
    int capacity;//记录当前通讯录的最大容量
} Contact;


//声明函数

//初始化通讯录
void InitContact(Contact *pc);

//增加联系人
void AddContact(Contact *pc);

//打印联系人信息
void PrintContact(const Contact *pc);

//删除联系人的信息
void DelContact(Contact *pc);

//查找指定联系人
void SearchContact(Contact *pc);

//修改指定联系人
void ModifyContact(Contact *pc);

//销毁通讯录
void DestoryContact(Contact *pc);

//保存通讯录信息到文件
void SaveContact(Contact *pc);

//加载文件内容到通讯录
void LoadContact(Contact *pc);

//检测增容的问题
void CheckCapacity(Contact *pc);

#endif //CONTACT_CONTACT_H

contact.c

//
// Created by Tian baby on 2022/2/9.
//
#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//静态版本的
// void InitContact(Contact* pc)
// {
// 	pc->sz = 0;//设置通讯录最初只有0个元素
// 	//memset(); 内存设置  将所有的空间初始化为0
// 	memset(pc->data, 0, sizeof(pc->data));
// }


//动态版本-初始化
//给data申请一块连续的空间再堆区上
//sz=0
//capacity 初始化为当前的最大的容量
void InitContact(Contact *pc) {
    pc->data = (PeoInfo *) malloc(DEFAULT_SZ * sizeof(PeoInfo));
    if (pc->data == NULL) {
        perror("InitContact");
        return;
    }
    pc->sz = 0;//初始化后默认是0
    pc->capacity = DEFAULT_SZ;

    //加载文件
    LoadContact(pc);
}

void DestoryContact(Contact *pc) {
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->capacity = 0;
}


void SaveContact(Contact *pc) {
    FILE *pf = fopen("contact.dat", "w");
    if (pf == NULL) {
        perror("SaveContact");
        return;
    }
    //写文件
    int i = 0;
    for (i = 0; i < pc->sz; i++) {
        fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
    }

    //关闭文件
    fclose(pf);
    pf = NULL;
}

void LoadContact(Contact *pc) {
    FILE *pf = fopen("contact.dat", "r");
    if (pf == NULL) {
        perror("LoadContact");
        return;
    }
    //读文件
    PeoInfo tmp = {0};
    while (fread(&tmp, sizeof(PeoInfo), 1, pf)) {
        //是否需要增容
        CheckCapacity(pc);
        pc->data[pc->sz] = tmp;
        pc->sz++;
    }

    //关闭文件
    fclose(pf);
    pf = NULL;
}

//
// 静态版本的-增加联系人
// void AddContact(Contact* 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].tele);
// 	printf("请输入地址:>");
// 	scanf("%s", pc->data[pc->sz].addr);
//
// 	pc->sz++;
// 	printf("增加成功\n");
// }

void CheckCapacity(Contact *pc) {
    if (pc->sz == pc->capacity) {
        PeoInfo *ptr = (PeoInfo *) realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
        if (ptr != NULL) {
            pc->data = ptr;
            pc->capacity += INC_SZ;
            printf("增容成功\n");
        } else {
            perror("AddContact");
            printf("增加联系人失败\n");
            return;
        }
    }
}

//动态版本- 增加联系人
void AddContact(Contact *pc) {
    //考虑增容
    CheckCapacity(pc);
    //增加一个人的信息
    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].tele);
    printf("请输入地址:>");
    scanf("%s", pc->data[pc->sz].addr);

    pc->sz++;
    printf("增加成功\n");
}


void PrintContact(const Contact *pc) {
    //通讯录为空情况和不为空的情况
    if (pc->sz == 0) printf("通讯录为空\n");
    else {
        int i = 0;
        //打印标题
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
        //打印信息
        for (i = 0; i < pc->sz; i++) {
            //打印一个人的信息
            printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
                   pc->data[i].name,
                   pc->data[i].age,
                   pc->data[i].sex,
                   pc->data[i].tele,
                   pc->data[i].addr);
        }
    }
}

static int FindByName(const Contact *pc, char name[]) {
    int i = 0;
    for (i = 0; i < pc->sz; i++) {
        //字符串之间的比较时用的strcmp
        if (strcmp(pc->data[i].name, name) == 0) {
            //如果找到返回下标找不到返回-1;
            return i;
        }
    }

    return -1;//找不到
}

void DelContact(Contact *pc) {
    char name[MAX_NAME] = {0};
    //通讯录为空,无法进行删除的情况
    if (pc->sz == 0) {
        printf("通讯录为空,无需删除\n");
        return;
    }
    //进行删除前的准备
    printf("请输入要删除人的名字:>");
    scanf("%s", name);

    //1. 查找要删除的人在什么位置
    //有/没有
    int pos = FindByName(pc, name);
    if (pos == -1) {
        printf("要删除的人不存在\n");
        return;
    }
    //2. 删除
    //从要删除的位置开始逐一向前移动
    int i = 0;
    //注意终止条件
    for (i = pos; i < pc->sz - 1; i++) {
        pc->data[i] = pc->data[i + 1];
    }
    pc->sz--;
    printf("删除成功\n");
}


void SearchContact(Contact *pc) {
    //存储要查找人的信息
    char name[MAX_NAME] = {0};
    printf("请输入要查找人的名字:>");
    scanf("%s", name);
    //查找
    int pos = FindByName(pc, name);
    //要查找人不存在
    if (pos == -1) {
        printf("要查找的人不存在\n");
        return;
        //可以查找到 打印被查找人的信息
    } else {
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
        //打印数据
        printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",
               pc->data[pos].name,
               pc->data[pos].age,
               pc->data[pos].sex,
               pc->data[pos].tele,
               pc->data[pos].addr);
    }
}

//修改指定联系人信息。
void ModifyContact(Contact *pc) {
    char name[MAX_NAME] = {0};
    printf("请输入要修改人的名字:>");
    scanf("%s", name);

    int pos = FindByName(pc, name);
    if (pos == -1) {
        printf("要修改的人不存在\n");
        return;
    } else {
        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].tele);
        printf("请输入地址:>");
        scanf("%s", pc->data[pos].addr);

        printf("修改成功\n");
    }
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 20:56:33  更:2022-02-14 20:56:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:35:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码