C语言版动态通讯录(增、删、改、查(查重)、去重、排序、导出)


一段学习过后,想写小东西加深下印象和理解,便开始了我的动态通讯录之旅。

整体框架及实现

通讯录主体
typedef struct content
{
//姓名
char name[Max_name];
//电话
char tel[Max_tel];
//性别
char sex[2];
//年龄
int age;
//住址
char addr[Max_adre];
//生日
char birthday[5];
//公司
char company[20];
}Content;

通讯录功能说明:

1、通讯录基础功能:增、删、改、查。
2、查重(以姓名查重)。
3、排序(以姓名拼音排序)。
4、文件导出,以自定义文件名及类型的形式进行导出。
5、文件去重。
6、数据保存加载(程序关闭后二次打开可以加载历史记录信息)。

编译环境–Visual Studio 2022**
**如果程序出现访问内存被破坏的问题,请照如下设置。

主菜单界面

详细代码

1、Contact.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#include <errno.h>
#define Max_name 11
#define Max_tel 12
#define Max_adre 10
#define init_capcity 5
#define Max_capcity 1000
#define Max_filename 20
//通讯录内容体typedef struct content
{//姓名char name[Max_name];//电话char tel[Max_tel];//性别char sex[2];//年龄int age;//住址char addr[Max_adre];//生日char birthday[5];//公司char company[20];
}Content;//通讯录结构体
typedef struct contact
{int Capcity;int size;Content* data;
}Contact;//统计数组
typedef struct MyStruct
{int num;char cou[0];
} count;
enum contact_option
{EXIT,ADD,DEL,EDIT,SEARCH,SHOW,SORT,EXPORT,DeDuplication,
};Contact* capcity_Expansion(Contact* p, int num);
int Init_contact(Contact* p, FILE* fp);
void MENU();
char Del_Contact(Contact* p);
void Add_Contact(Contact* p);
void Sort_Contact(Contact* p);
void Show_Contact(Contact* p);
void DeDuplication_Contact(Contact* p);
char Edit_Contact(Contact* p);
int Export_Contact(Contact* p);
void Contact_main();
void Load_Contact(Contact* p);
void Save_Contact(Contact* p);
count* Search_Contact(Contact* p, char name[Max_name]);

2、Contact.c

#include"Contact.h"//interface 调用入口void Contact_main()
{//读取本地文件FILE* fp;fp = fopen("MyContact.dat", "rb+");while (fp == NULL){perror("Failed to load local file:");printf("Created a file named MyContact.txt!\n");fp = fopen("MyContact.dat", "wb+");}static int user_input = 0;Contact My_contact;//初始化通讯录Init_contact(&My_contact, fp);do{MENU();printf("Please Select >>\n");scanf("%d", &user_input);switch (user_input){case ADD:Add_Contact(&My_contact);break;case DEL:Del_Contact(&My_contact);break;case EDIT:Edit_Contact(&My_contact);break;case SEARCH://调用显示char name[Max_name];printf("请输入要查询的人的姓名: >>\n");scanf("%s", name);Contact* p = &My_contact;count* index_name = Search_Contact(p, name);int num = index_name->num;if (num >= 1){//打印所有符合筛选条件的人的信息printf("%-11s\t%-12s\t%-3s\t%-10s\t%-3s\t%-4s\t%-20s\n\n", "姓名", "电话", "性别", "地址", "年龄", "生日", "公司");int j;int k = 0;for (j = index_name->cou[0]; j <= index_name->num; j++){printf(" %-11s\t%-12s\t%-3s\t%-10s\t%-3d\t%-4s\t%-20s\n",p->data[index_name->cou[k]].name,p->data[index_name->cou[k]].tel,p->data[index_name->cou[k]].sex,p->data[index_name->cou[k]].addr,p->data[index_name->cou[k]].age,p->data[index_name->cou[k]].birthday,p->data[index_name->cou[k]].company);k += 1;}}break;case SHOW:Show_Contact(&My_contact);break;case SORT:Sort_Contact(&My_contact);break;case EXPORT:Export_Contact(&My_contact);break;case DeDuplication:DeDuplication_Contact(&My_contact);case EXIT:Save_Contact(&My_contact);printf(">>>welcome to use it ! <<<\n");exit;break;default:printf("Input error ! Please tyr again!! >> \n");break;}} while (user_input);
}
void MENU()
{printf("\n\n");printf("====================================================\n");printf("===----------------------------------------------===\n");printf("===********       My Contact V1.0        ********===\n");printf("===----------------------------------------------===\n");printf("===********    1、添加       2、删除     ********===\n");printf("===----------------------------------------------===\n");printf("===********    3、修改       4、查询     ********===\n");printf("===----------------------------------------------===\n");printf("===********    5、显示       6、排序     ********===\n");printf("===----------------------------------------------===\n");printf("===********    7、导出       8、去重     ********===\n");printf("===----------------------------------------------===\n");printf("===********           0、退出            ********===\n");printf("===----------------------------------------------===\n");printf("====================================================\n");printf("\n\n");return 0;
}/*
初始化通讯录,加载本地文件读取通讯录信息
函数返回值0:初始化失败、1:初始化成功
*/int Init_contact(Contact* p, FILE* fp)
{assert(p, fp);int status;Content* tmp = 0;tmp = (Content*)malloc(sizeof(Content) * init_capcity);if (tmp){p->data = tmp;p->size = 0;p->Capcity = init_capcity;Load_Contact(p);status = 1;}else{printf("%s", strerror(errno));status = 0;}return status;
}/*扩容方法,返回访问地址*/Contact* capcity_Expansion(Contact* p, int num)
{assert(p);Content* tmp = 0;tmp = realloc(p->data, sizeof(Content) * (num + p->Capcity));if (tmp != NULL){printf(">>>>>扩容成功\n");p->data = tmp;p->Capcity += num;}else{printf(">>>>>扩容失败\n");printf(">>>>>错误信息:%s\n", strerror(errno));}return p;
}/*
用户录入函数,传入录入起始位置索引,无参则默认起始位置传参
返回录入状态,返回1则录入成功,0:录入失败
*/
int UserInput(Contact* p)
{assert(p != NULL);//判断容量是否满足if (p->Capcity < 2){//容量不足时,自动扩容,每次加3capcity_Expansion(p, 3);}int status = 0;printf("please input name:>>");scanf("%s", p->data[p->size].name);printf("please input telephone:>>");scanf("%s", p->data[p->size].tel);printf("please input sex:>>");scanf("%s", p->data[p->size].sex);printf("please input address:>>");scanf("%s", p->data[p->size].addr);printf("please input age:>>");scanf("%d", &(p->data[p->size].age));printf("please input birthday:>>");scanf("%s", p->data[p->size].birthday);printf("please input company:>>");scanf("%s", p->data[p->size].company);p->size += 1;p->Capcity -= 1;status = 1;return status;
}//加载文件函数void Load_Contact(Contact* p)
{//读取本地文件,写入contentFILE* fp;Content TEMP = { 0 };fp = fopen("MyContact.dat", "rb+");if (fp == NULL){perror("File load Fault :");return;}else{while (fread(&TEMP, sizeof(Content), 1, fp)){if (p->Capcity <= 2){capcity_Expansion(p, 2);}p->data[p->size] = TEMP;p->size += 1;}printf("File Load Sucess!!\n");}fclose(fp);fp = NULL;return;
}//保存写入函数
void Save_Contact(Contact* p)
{assert(p);FILE* fp;fp = fopen("MyContact.dat", "wb+");if (fp == NULL){perror("写入失败:");return;}else{//fwrite(p, sizeof(Content), 1, fp);int i;for (i = 0; i < p->size; i++){/*循环写入*/fwrite(&(p->data[i]), sizeof(Content), 1, fp);}fclose(fp);fp = NULL;printf("保存成功!!\n");}return;
}//添加函数
void Add_Contact(Contact* p)
{assert(p);if (UserInput(p)){printf("添加成功!!\n");printf("\n\n通讯录容量: <-可用-> -- %d /<-已用-> --%d \n", p->Capcity, p->size);}else{printf("添加失败,请重试\n");}return 0;
}//删除函数char Del_Contact(Contact* p)
{assert(p);//判断通讯录是否为空if (p->size == 0){printf("the contact is empty\n");}else{char name[Max_name] = { 0 };printf("please input name:>>\n");scanf("%s", name);printf("%s", name);count* index;int i;int j = 0;index = Search_Contact(p, name);int num = index->num;for (i = index->cou[j]; i < p->size; i++){//如果出现重复元素 if ((i + 1) == index->cou[j]){i = i + 1;}p->data[i] = p->data[i + 1];j++;}p->size -= num;p->Capcity += num;printf("delete sucess!!\n");free(index);index = NULL;}return 0;
}//修改函数char Edit_Contact(Contact* p)
{assert(p);char name[Max_name];printf("请输入要编辑的人的姓名 >>\n");scanf("%s", name);count* index_name = Search_Contact(p, name);int num = index_name->num;if (num > 1){//打印所有符合筛选条件的人的信息printf("%-11s\t%-12s\t%-3s\t%-10s\t%-3s\t%-4s\t%-20s\n\n", "姓名", "电话", "性别", "地址", "年龄", "生日", "公司");int j;int k = 0;for (j = index_name->cou[0]; j <= index_name->num; j++){printf(" %-11s\t%-12s\t%-3s\t%-10s\t%-3d\t%-4s\t%-20s\n",p->data[index_name->cou[k]].name,p->data[index_name->cou[k]].tel,p->data[index_name->cou[k]].sex,p->data[index_name->cou[k]].addr,p->data[index_name->cou[k]].age,p->data[index_name->cou[k]].birthday,p->data[index_name->cou[k]].company);k += 1;}}int i;for (i = 0; i < num; i++){printf("please input new meassage 第 %d 位:>>", (i + 1));scanf("%s", p->data[index_name->cou[i]].name);printf("please input new telephone:>>");scanf("%d", p->data[index_name->cou[i]].tel);printf("please input new sex:>>");scanf("%s", p->data[index_name->cou[i]].sex);printf("please input new age:>>");scanf("%d", &(p->data[index_name->cou[i]].age));printf("please input new address:>>");scanf("%s", p->data[index_name->cou[i]].addr);printf("please input new birthday:>>");scanf("%s", p->data[index_name->cou[i]].birthday);printf("please input new company:>>");scanf("%s", p->data[index_name->cou[i]].company);}Show_Contact(p);return 0;
}//查询函数
count* Search_Contact(Contact* p, char name[Max_name])
{assert(p);//定义一个数组,存放符合搜索条件人的信息的索引static count* C1;C1 = (count*)malloc(sizeof(count) + sizeof(char) * 5);if (C1 == NULL){printf("%s", strerror(errno));}C1->num = 0;C1->cou[0] = 0;int i, j;j = 0;for (i = 0; i < p->size; i++){if (0 == strcmp(name, p->data[i].name)){C1->cou[j++] = i;};}C1->num = j;return C1;
}
//打印函数 打印通讯录
void Show_Contact(Contact* p)
{char Input;if (p->size == 0){printf("Contact is Null,To Add?(Y/N)\n");scanf("%s", &Input);if (Input == 'y' || Input == 'Y'){Add_Contact(p);Show_Contact(p);}else{return(-1);/*Exit_Contact();*/}}else{printf("%-11s\t%-12s\t%-3s\t%-10s\t%-3s\t%-4s\t%-20s\n\n", "姓名", "电话", "性别", "地址", "年龄", "生日", "公司");int i = 0;for (i = 0; i < p->size; i++){printf(" %-11s\t%-12s\t%-3s\t%-10s\t%-3d\t%-4s\t%-20s\n",p->data[i].name,p->data[i].tel,p->data[i].sex,p->data[i].addr,p->data[i].age,p->data[i].birthday,p->data[i].company);}printf("\n\nyour contact capcity meassage: <Used> -- %d /<Usable> --%d \n", p->Capcity, p->size);}return(-1);
}//排序定义函数int cmp_string(const void* _a, const void* _b)
{char* a = (char*)_a;char* b = (char*)_b;return strcmp(a, b);
}
// 排序函数
void Sort_Contact(Contact* p)
{/*按照姓姓名首字母排序使用排序算法(冒泡)*/assert(p);int i, j;for (i = 0; i < p->size; i++){for (j = 0; j < (p->size) - i - 1; j++){if (*(p->data[j].name) > *(p->data[j + 1].name)){//首字母拼音在前,则交换顺序Content temp;temp = p->data[j];p->data[j] = p->data[j + 1];p->data[j + 1] = temp;}}}//调用显示函数打印Show_Contact(p);return 0;
}//去重函数void DeDuplication_Contact(Contact* p)
{//遍历通讯录,将姓名相同人的信息进行记录assert(p);//找出所有重复姓名的索引,将其删除或提示更新数据static char REpeat_name[Max_capcity][Max_name];int i;int k = 0;for (i = 0; i < p->size; i++){int j;for (j = i + 1; j < p->size; j++){//如果名字出现过,记录索引if (strcmp(p->data[i].name, p->data[j].name) == 0){REpeat_name[k][0] = i;REpeat_name[k + 1][0] = j;k += 2;}}}if (k){//有重复信息,将重复信息进行显示printf("%-11s\t%-12s\t%-3s\t%-10s\t%-3s\t%-4s\t%-20s\n\n", "姓名", "电话", "性别", "地址", "年龄", "生日", "公司");for (int i = 0; i < k; i++){printf(" %-11s\t%-12s\t%-3s\t%-10s\t%-3d\t%-4s\t%-20s\n",p->data[REpeat_name[i][0]].name,p->data[REpeat_name[i][0]].tel,p->data[REpeat_name[i][0]].sex,p->data[REpeat_name[i][0]].addr,p->data[REpeat_name[i][0]].age,p->data[REpeat_name[i][0]].birthday,p->data[REpeat_name[i][0]].company);}char input_repeat;printf("对重复信息进行删除(Y/N)>>\n");scanf("%s", &input_repeat);if (input_repeat == 'y' || input_repeat == 'Y'){//删除int f = 0;for (int i = REpeat_name[f][0]; i < p->size; i++){//如果出现重复元素 if ((i + 1) == REpeat_name[f + 1][0]){i = i + 1;}p->data[i] = p->data[i + 1];f++;}p->size -= k;p->Capcity += k;printf("delete sucess!!\n");}else{return;}}else{printf("通讯录内无重复姓名信息!>>\n");Show_Contact(p);}return;
}//将文件导出指定的文件名内(二进制写)int Export_Contact(Contact* p)
{assert(p);int status = 0;char Filename[Max_filename];printf("请输入文件名:>>\n");scanf("%s", Filename);FILE* fp_export;fp_export = fopen(Filename, "wb+");if (fp_export == NULL){perror("写入失败:");return;}else{int i;for (i = 0; i < p->size; i++){/*循环写入*/fwrite(&(p->data[i]), sizeof(Content), 1, fp_export);}fclose(fp_export);fp_export = NULL;printf("保存成功!!\n");status = 1;}fclose(fp_export);fp_export = NULL;return status;
}

3、test.c


void main()
{Contact_main();return 0;
}

第一次分享博客,如有问题,还请各位博友不吝赐教。

C语言版动态通讯录(增、删、改、查(查重)、去重、排序、导出)相关推荐

  1. 表单的增 删 改 查

    django单表操作 增 删 改 查 一.实现:增.删.改.查 1.获取所有数据显示在页面上 model.Classes.object.all(),拿到数据后,渲染给前端;前端通过for循环的方式,取 ...

  2. properties(map)增.删.改.查.遍历

    import java.util.Map; import java.util.Properties; import java.util.Set;/*** properties(map)增.删.改.查. ...

  3. datatable更新到mysql_.NET_使用DataTable更新数据库(增,删,改),1、修改数据复制代码 代码如 - phpStudy...

    使用DataTable更新数据库(增,删,改) 1.修改数据 DataRow dr = hRDataSet.Tables["emp"].Rows.Find(textBox3.Tex ...

  4. python学生姓名添加删除_python-函数-实现学生管理系统,完成对学员的增,删,改,查和退出学生管理系统。...

    实现学生管理系统,完成对学员的增,删,改,查和退出学生管理系统. 要求1:使用一个list用于保存学生的姓名. 要求2:输入0显示所有学员信息,1代表增加,2代表删除,3代表修改,4代表查询,exit ...

  5. java stringbuilder 替换字符串_StringBuilder修改字符串内容,增,删,改,插

    package seday01; /** * 字符串不变对象特性只针对字符串重用,并没有考虑修改操作的性能.因此String不适合频繁修改内容. * 若有频繁修改操作,使用StringBuilder来 ...

  6. PySpark︱DataFrame操作指南:增/删/改/查/合并/统计与数据处理

    笔者最近需要使用pyspark进行数据整理,于是乎给自己整理一份使用指南.pyspark.dataframe跟pandas的差别还是挺大的. 文章目录 1.-------- 查 -------- -- ...

  7. C语言实现动态通讯录版本二

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.通讯录的实现 1.通讯录需要的库函数以及各种功能的自定义函数声明(contact.h) 2.自定义函数实现模块(con ...

  8. 学生信息管理系统——JAVA 语言版(主页面+增+删+改+查+退)

    学生信息管理系统 前言 一.问题分析 二.学生信息管理系统程序实现思路 三.Student类的创建 程序思路 Student类代码 四.StudentManager类的创建 程序思路 StudentM ...

  9. 数据结构 严薇敏 顺序表的实现(增 删 改)及其使用方法详解

    时间复杂度 数据结构 时间复杂度和空间复杂度 目录 1.线性表 2.顺序表 2.1概念及结构 2.2 接口实现 SeqList.h SeqList.c 2.2.1初始化链表以及销毁链表的实现 初始化顺 ...

最新文章

  1. oracle 用mybatis生成主键
  2. 梳理:python—同一个类中的方法调用
  3. php 刷新iframe,js刷新iframe
  4. bat 发邮件与手机交互_售价17500元!华为首款5G折叠屏手机来了,更多新机细节曝光...
  5. WindowsServer 2008 Ad建立ftp隔离用户
  6. C#常用集合的使用(转载)
  7. 软件工程师的十个“不职业”行为
  8. python邮箱爆破_Python在线爆破邮箱账号密码测试代码(亲测可用)
  9. python3导入_Python3导入相对还是绝对的正确方法?
  10. 张朝阳直播带货首秀 带的不仅是好物而是价值平台
  11. 表格送货单自动编号vba_制作仓库入库单,自动登记商品数据,这段代码只需三步搞定...
  12. 光纤通信是不是计算机类的,光纤通信专业属于什么门类
  13. 教团1886:高端的半成品电影
  14. 英语单词听力测试软件,英语单词发音软件
  15. 5个小技巧,让你的for循环瞬间高大上!
  16. 精囊妙计 -- 策略模式(Strategy Pattern) 介绍 优缺点 使用场景案例及代码演示
  17. Process-wide API spying - an ultimate hack 摘要翻译(三)
  18. html中怎么让div撑开,html中子div用了浮动怎样让父div的大小自动撑开(清除浮动)...
  19. 世上最经典的爱情诗句
  20. mysql 过滤emoji表情_MySQL中emoji表情过滤

热门文章

  1. 面试——Java字节面经(已获Offer)
  2. Linux 指令:怎样从文件中找到重复行?
  3. matlab画简单长方形,matlab在图像中画长方形(框)
  4. Python爬虫实战——蚂蜂窝国内目的地全抓取
  5. android 常用短语的添加,LazyBoard – 常用短语键盘,快速输入很长的句子
  6. 45. Jump Game II(跳跃游戏II)
  7. 花千骨服务器无响应,花千骨出现游戏闪退 解决闪退方案
  8. 扫盲贴:手游圈行业术语汇总
  9. 加百利号角/托里拆利小号
  10. Java Web实现登录注册(超详细附代码)