首页 > 其他分享 >通讯录

通讯录

时间:2024-03-22 09:15:17浏览次数:14  
标签:void 联系人 pc 通讯录 printf data

test.c

define _CRT_SECURE_NO_WARNINGS

include "contact.h"

void menu()
{
printf("\n");
printf("
1.add 2.del \n");
printf("
3.seach 4.modify \n");
printf("
5.show 6.sort \n");
printf("
0.exit \n");
printf("
****\n");
}

int main()
{
int input = 0; //不能把input放进do里
PeoInfo data[100]; //说明通讯录的数据总数
int count = 0; //用于记录当前通讯录的个数
Contact con; //创建一个通讯录
InitContact(&con); //初始化通讯录,把con的地址作为形参
do
{
menu();
printf("请选择:> ");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con); //实现向通讯录中添加数据
break;
case 2:
DelContact(&con);
break;
case 3:
SeachContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
SortContact(&con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}

contact.c

define _CRT_SECURE_NO_WARNINGS

include "contact.h"

//静态版本初始化通讯录
//void InitContact(Contact* pc)
//{
// assert(pc); //断言防止pc为空指针
// pc->count = 0; //pc指向的count等于0,因为刚创建的通讯录什么都没有
// memset(pc->data, 0, sizeof(pc->data)); //用memset内存设置函数把一段连续的内存空间设置为0
//}

//动态版本通讯录
int InitContact(Contact* pc)
{
assert(pc);
pc->count = 0;
pc->data = (PeoInfo*)malloc(3, sizeof(PeoInfo));//用malloc函数申请3段空间每段空间大小就是在通讯录中存放一个联系人所需要的空间大小
//malloc函数的3表示要申请的空间个数,sizeof(PeoInfo)表示申请的每个空间的大小
if(pc->data == NULL)
{
printf("%s\n",strerror(errno));
return 1;
}
pc->pacacity = 3;//如果pc->data返回的不是空指针说明内存申请成功,把容量置3
return 0;
}

//静态版本添加联系人到通讯录
void AddContact(Contact* pc)
{
assert(pc);
if (pc->count == MAX)
{
printf("人数已满,无法添加\n");
return;
}
else
{
printf("请输入名字:>\n");
scanf("%s", pc->data[pc->count].name);
//pc->data[pc->count].name 表示要将读取的字符串存储在通讯录中的一个联系人的名称字段中。
//pc 是指向 Contact 结构体的指针。
// data 是 Contact 结构体中的一个成员,它是一个数组,用于存储联系人的信息。
//pc->count 是当前通讯录中已经存在的联系人数量。
// .name 是联系人结构体中的一个成员,表示联系人的名称字段。
// 因此,这行代码的作用是从用户输入中读取一个字符串,并将其存储在通讯录中的一个联系人的名称字段中。
printf("请输入年龄:>\n");
scanf("%d", &(pc->data[pc->count].age)); //因为这里打印的是一个整形
printf("请输入性别:>\n");
scanf("%s", pc->data[pc->count].sex);
printf("请输入电话:>\n");
scanf("%s", pc->data[pc->count].tele);
printf("请输入地址:>\n");
scanf("%s", pc->data[pc->count].addr);

    pc->count++;        //添加联系人到通讯录后通讯录的实际联系人要加1;
}

}

//动态版本添加联系人到通讯录
void AddContact(Contact* pc)
{
assert(pc);
if (pc->count == pc->capacity)
{
PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
//判断实际人数是否满容量如果满就扩容
if(ptr == NULL)
{
printf("AddContact::%s\n", strerror(error));//有可能扩容失败,判断ptr接收到的是否为空指针若为空则输出错误信息
return;
}
else
{
pc->data = ptr;
pc->capacity += INC_SZ;
}
}
printf("请输入名字:>\n");
scanf("%s", pc->data[pc->count].name);
//pc->data[pc->count].name 表示要将读取的字符串存储在通讯录中的一个联系人的名称字段中。
//pc 是指向 Contact 结构体的指针。
// data 是 Contact 结构体中的一个成员,它是一个数组,用于存储联系人的信息。
//pc->count 是当前通讯录中已经存在的联系人数量。
// .name 是联系人结构体中的一个成员,表示联系人的名称字段。
// 因此,这行代码的作用是从用户输入中读取一个字符串,并将其存储在通讯录中的一个联系人的名称字段中。
printf("请输入年龄:>\n");
scanf("%d", &(pc->data[pc->count].age)); //因为这里打印的是一个整形
printf("请输入性别:>\n");
scanf("%s", pc->data[pc->count].sex);
printf("请输入电话:>\n");
scanf("%s", pc->data[pc->count].tele);
printf("请输入地址:>\n");
scanf("%s", pc->data[pc->count].addr);

pc->count++;        //添加联系人到通讯录后通讯录的实际联系人要加1;

}

//打印通讯录
void ShowContact(const Contact* pc)
{
assert(pc);
int i = 0;
printf("%-18s\t %-2s\t %-4s\t %-11s\t %-29s\n", "名字", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-6d\t%-7s\t%-14s\t%-30s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}

int FindName(Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (strcmp(pc->data[i].name, name) == 0) //等于0说明它们相等
{
return i; //返回i是为了方便记录是第几个联系人
}
}
return -1; //找不到就返回-1
}

//删除通讯录指定联系人 要找到了才能删除
void DelContact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要删除的联系人的名字:> ");
scanf("%s", name);
int ret = FindName(pc, name);
int i = 0;
if (ret == -1)
{
printf("找不到要删除的联系人\n");
return;
}
for (i = ret; i < pc->count; i++) //这段代码的作用是将被删除联系人后面的联系人向前移动一个位置,
//然后将通讯录中的联系人数量减一。
{
pc->data[i] = pc->data[i + 1];
}
pc->count--; //这样做的目的是确保通讯录的联系人数量与实际的联系人数量保持一致,
//避免出现无效的联系人信息或访问越界的情况。实际的联系人就只有pc->count个这么多

printf("删除成功\n");

}

//查找联系人
void SeachContact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要查找联系人的名字:> ");
scanf("%s", name);
//查找
int ret = FindName(pc, name);
if (ret == -1)
{
printf("要查找的联系人不存在\n");
return;
}
//打印
printf("%-18s\t %-2s\t %-4s\t %-11s\t %-29s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-20s\t%-6d\t%-7s\t%-14s\t%-30s\n", pc->data[ret].name,
pc->data[ret].age,
pc->data[ret].sex,
pc->data[ret].tele,
pc->data[ret].addr);
}

//修改指定联系人
void ModifyContact(Contact* pc)
{
assert(pc);
char name[MAX_NAME] = { 0 };
printf("请输入要修改联系人的名字:> ");
scanf("%s", name);
//查找
int ret = FindName(pc, name);
if (ret == -1)
{
printf("找不到相应的的联系人不存在\n");
return;
}
printf("要修改的联系人已找到现在开始修改\n");
//修改
printf("请输入名字:>\n");
scanf("%s", pc->data[ret].name);
printf("请输入年龄:>\n");
scanf("%d", &(pc->data[ret].age));
printf("请输入性别:>\n");
scanf("%s", pc->data[ret].sex);
printf("请输入电话:>\n");
scanf("%s", pc->data[ret].tele);
printf("请输入地址:>\n");
scanf("%s", pc->data[ret].addr);

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

}

int CmpName(void* e1, void* e2)
{
return strcmp(((PeoInfo)e1)->name, ((PeoInfo)e2)->name);
}

//首字母大小排序
void SortContact(Contact* pc)
{
assert(pc);
//void qsort (void* base, size_t num, size_t size, int (compar)(const void, const void*));
qsort(pc->data, pc->count, sizeof(PeoInfo), CmpName);
printf("排序成功\n");
}

contact.h

pragma once

include <stdio.h>

include <assert.h>

include <string.h>

include <stdlib.h>

//宏定义后面不能加分号和注释

define INC_SZ 2

define MAX 100

define MAX_NAME 20

define MAX_SEX 10

define MAX_TELE 12

define MAX_ADDR 30

//类型的声明,声明一个结构体,里面放有通讯录的数据类型和大小,也就是人的信息
typedef struct PeoInfo
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;

//通讯录
//静态版本
typedef struct Contact
{
PeoInfo data[MAX]; //用于存放人的信息
int count; //用于记录当前通讯录的实际人数 定义结构体不能在结构体内部直接初始化变量
}Contact;

//动态版本初始化通讯录,通讯录默认存放3个人的信息,若空间不够了每次增加2个人的空间
//typedef struct Contact
{
PeoInfo* data;//用于存放人的信息
int count;//用于记录通讯录实际联系人的个数
int capacity;//用于记录当前通讯录的容量,方便判断通讯录是否满容量,若满了就扩容
}

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

//添加联系人到通讯录
void AddContact(Contact* pc);

//动态版本添加联系人到通讯录
void AddContact(Contact* pc);

//打印通讯录
void ShowContact(const Contact* pc);

//删除通讯录的联系人
void DelContact(Contact* pc);

//查找联系人
void SeachContact(Contact* pc);

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

//首字母大小排序
void SortContact(Contact* pc);

课堂杂记
malloc函数:
void* malloc (size_t size);
1.这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
2.如果开辟成功,则返回一个指向开辟好空间的指针。
3.如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
4.返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
5.如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器

free函数:
void free(void* ptr);
free函数用来释放动态开辟的内存。
1.如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
2.如果参数 ptr 是NULL指针,则函数什么事都不做。
malloc和free都声明在 stdlib.h 头文件中

calloc函数:
void* calloc (size_t num, size_t size);
1.函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
2.与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。

realloc函数:
void* realloc (void* ptr, size_t size);
1.ptr 是要调整的内存地址
2.size 调整之后新大小
3.返回值为调整之后的内存起始位置。
4.这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
realloc函数调整内存有两种情况:
1.原有空间后面有足够的未被占用的空间,直接在原有空间后面调整就行;
2.原有空间后面没有足够的空间,此时realloc函数会在一个有足够的未被占用的空间处开辟出一段连续的空间,并把原有空间的内容复制到新的空间,原有的空间会被释放;

标签:void,联系人,pc,通讯录,printf,data
From: https://www.cnblogs.com/lwd107/p/18088642

相关文章

  • 通讯录实现!(基于顺序表的项目)
    一.通讯录实现要求c语言基础要求:结构体、动态内存管理、顺序表、文件操作二、通讯录功能能够保存用户信息、能够增加联系人、删除联系人、查找联系人、修改联系人信息、显示联系人信息三、通讯录实现通讯录实现90%是基于之前的顺序表的,所以想要实现通讯录可以先去看看我有......
  • 通讯录管理系统学习记录
    黑马C++通讯录管理系统案例学习记录,并添加课堂上讲的部分功能。1.系统需求系统中需要实现的功能如下:添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人显示联系人:显示通讯录中所有联系人信息删除联系人:按照姓名进行删除指定联系......
  • 【C语言进阶篇】模拟实现通讯录 (内附源码)
    (文章目录)......
  • 通讯录(动态增长版本)——《初学C语言第52天》
    contact.h////此通讯录为静态的版本(设置多少量就是多少,量的大小无法调整)////动态版本:需要多少就给多少,不够用了就开辟新空间,多了就自动减少////文件版本:动、静两种只要退出通讯录,保存的信息就消失了,而文件版本会依旧保存#define_CRT_SECURE_NO_WARNINGS1#define MAX100#define......
  • 通讯录(静态)——《初学C语言第47天》
    cotact.h#define_CRT_SECURE_NO_WARNINGS1#define MAX100#define MAXname20#define MAXsex10#define MAXtre12#define MAXaddr30#include<stdio.h>#include<string.h>#include<assert.h>#include<stdlib.h>//类型声明//人的信息typedefstructp{......
  • 手机通讯录好备份,那微信通讯录怎么备份出来
    6-8众所周知的是,手机通讯录是很好备份的,但是微信不行,手机本身就带有备份功能,换手机可以快速地迁移通讯录,比如下面这个就是小米手机自带的备份功能,简单好用但是现在生意可都在微信上做了,微信又有封号、交接工作的可能,微信上的通讯录怎么导出来,就是个大问题,因为微信本身就不提供这种......
  • C语言小项目-通讯录
    对C语言的学习研究也有一段时间了,今天做一个小项目“通讯录”,来回顾之前所学。文件结构通讯录这个项目需要三个文件:1.test.c用于测试2.contact.c用于实现3.contact.h声明函数需求描述1.该通讯录要能存放1000个好友的信息2.信息要包含:姓名、电话、性别、住址、年龄3.增加好友信息......
  • 手机通讯录好备份,那微信通讯录怎么办
    6-8微信联系已经成为我们日常生活沟通联系最常用的渠道之一,那么对于通讯录的提前备份就越来越重要了,防患于未然。如果是手动一个个联系人去抄写备份的话会花很多时间,特别是有些通讯联系人比较多的朋友。这里有一个小工具《微信通讯录极速导出工具》,可以方便快速地一键导出所有的微......
  • 【实用小教程】如何批量导出、备份微信通讯录好友
    6-11对于有微信通讯录备份需求的人来说,要把微信的通讯录联系人的微信号、备注的手机号等信息弄出来,有不少困难,因为微信本身不提供这样的功能,所以如果要一个个抄,是不太现实的。本教程要解决的问题就是微信通讯录备份的问题,速度贼快,原理就是通过分析微信存储在本地的文件,直接从文件里......
  • 如何快速导出、备份微信通讯录好友联系人微信号
    6-9如果因工作需要,你有多个微信,并且你的业务开发的客户都在这些微信里,将会面临一个问题,那就是备份问题,因为通过微信做业务,如果遇到微信不小心被封号,或者离职的交接等情况,客户联系方式的损失是影响比较大的。所以一定要及时对微信的通讯录备份下来,如果你的习惯比较好,会将客户的手机......