C语言实现通讯录(低配版)
文章目录
- 一.准备
- 二.主文件
- 三.contact.h文件
- 3.1需要用到的宏定义,和函数所需的头文件
- 3.2结构体定义
- 3.3函数的声明
- 四.contact.c文件
- 4.1初始化通讯录信息Init_Contact
- 4.2添加联系人信息Add_contact
- 4.3查找联系人Find_Peo
- 4.4删除指定联系人信息Delete_Contact
- 4.5查找联系人
- 4.6修改联系人信息
- 4.7排序联系人信息
- 五.代码
- 5.1text.c
- 5.2contact.c
- 5.3contact.h
一.准备
首先我们要创建三个文件:
1.text.c主文件
2.contact.c文件,这个主要放的是实现通讯录有关的文件
3.contact.h文件,头文件,有函数的声明,结构体定义和一些宏定义
二.主文件
#include "contact.h"
void menu()
{
printf("****************************************\n");
printf("******** 1.添加 2.删除 ********\n");
printf("******** 3.全部删除 4.修改 ********\n");
printf("******** 5.查找 6.显示 ********\n");
printf("******** 7.排序 0.退出 ********\n");
printf("****************************************\n");
}
int main()
{
int input = 0;
struct Contact con;
//定义一个结构体con,结构体信息在contact.h里面
//初始化通讯录信息
Init_Contact(&con);
do
{
menu();
printf("请输入->");
scanf("%d", &input);
switch (input)
{
case ADD:
Add_contact(&con);
break;
case DELETE:
Delete_Contact(&con);
//全部删除就相当于初始化了
break;
case DELETE_ALL:
Init_Contact(&con);
break;
case AMEND:
Amend_Contact(&con);
break;
case FIND:
Find_Contact(&con);
break;
case SHOW:
Show_Contact(&con);
break;
case SORT:
Sort_Contact(&con);
break;
case EXIT:
break;
default:
printf("输入错误,请重新输入->\n");
break;
}
} while (input);
return 0;
}
这个放在主文件里。
main函数的主要框架是do while函数。这样就可以在执行一次循环之后,继续执行我们想要的内容。而不是在执行一次循环之后就退出去。
循环里面是switch语句。我们的通讯录里有8个命令:添加,删除,全部删除,修改,寻找,展示,排序,退出。
EXIT,ADD,DELETE,DELETE_ALL,AMEND,FIND,SHOW,SORT。这些都是枚举变量,是在contact.h里面定义好的。这些变量的值从0开始。
我们通过定义的input变量来控制这些。假设输入1,input的值就是1,对应的就是实现ADD对应的函数。
每个命令都对应这一个函数,这些函数在contact.c文件里实现。
程序一运行肯定要先初始化,初始化的代码放在contact.c文件里。
为了让使用者知道每个命令对应的按键,所以要有目录menu
menu函数自己定义好就行,这个函数比较简单,直接放在main函数上面就行。
#include “contact.h”
因为我们写的大部分参数和一些定义都在contact.h文件里,所以先包含contact.h,代码才能运行。
三.contact.h文件
3.1需要用到的宏定义,和函数所需的头文件
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10 //通讯录的大小,能装10个成员的信息
#define NAME 20 //联系人名字数组的长度
#define SEX 8 //联系人性别数组的长度
#define PHONE 12 //联系人电话数组的长度
#define LOCATION 15 //联系人地址数组的长度
3.2结构体定义
enum catalog
//枚举
{
EXIT, //退出
ADD, //添加联系人信息
DELETE, //删除联系人信息
DELETE_ALL,//删除所有人信息
AMEND, //修改联系人信息
FIND, //查找联系人
SHOW, //显示所有联系人信息
SORT, //排序联系人信息
};
//联系人信息
struct Contact_Person
{
char name[NAME]; //联系人姓名
char sex[SEX]; //联系人性别
char phone[PHONE]; //联系人电话
char location[LOCATION]; //联系人地址
};
//通讯录
struct Contact
{
int size;
struct Contact_Person data[SIZE];
};
主要讲一下结构体struct Contact
size是为了以后函数的使用,记录当前通讯录里联系人的个数。在初始化是size为0.
struct Contact_Person data[SIZE];是一个数组。
数组里有SIZE个成员,SIZE已经在上面宏定义好了,可自己调整大小。就是说通讯录最多能装SIZE个成员。每个成员的类型都是struct Contact_Person类型的。
struct Contact_Person是我们定义好的结构体。
总结一下:
我们把每个联系人的信息:姓名,性别,手机号,地址封装在一个结构体(struct Contact_Person)里。
然后我们在定义一个更大的结构体里面有成员size,是为了记录当前成员的个数。还有一个成员是一个数组,数组的每个成员都是struct Contact_Person类型的。也就是数组里的每个元素都是一个联系人的信息。
3.3函数的声明
//初始化通讯录信息
void Init_Contact(struct Contact* con);
//添加联系人信息
void Add_contact(struct Contact* con);
//显示所有联系人信息
void Show_Contact(struct Contact* con);
//删除指定联系人信息
void Delete_Contact(struct Contact* con);
//查找联系人
void Find_Contact(struct Contact* con);
//修改联系人信息
void Amend_Contact(struct Contact* con);
//排序联系人信息
void Sort_Contact(struct Contact* con);
这些就是我们在contact.c文件用到的函数
四.contact.c文件
4.1初始化通讯录信息Init_Contact
void Init_Contact(struct Contact* con)
{
con->size = 0;
memset(con->data, 0, sizeof(con->data));
}
我们将结构体里的size设置为0,说明此时通讯录里还没有成员
memset函数:
将结构体data数组里面的数据全部设置成0。
memset函数的用法:
void * memset ( void * ptr, int value, size_t num );
ptr:需要更改(填充)数据的内存块的地址,上面我们要更改的是数组data。
value:我们要把这个内存块的内容更改成value,上面我们要把数组里的内容变成0
size_t num:我们要把这个内存块的num个字节的内容改成value。上面我们用到的是sizeof(con->data),就是把整个数组大小的内容设置成0.这样就达到初始话的效果了。
4.2添加联系人信息Add_contact
void Add_contact(struct Contact* con)
{
system("cls");
if (con->size < SIZE)
{
printf("请输入联系人名字:");
scanf("%s", con->data[con->size].name);
printf("请输入联系人性别:");
scanf("%s", con->data[con->size].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[con->size].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[con->size].location);
con->size++;
}
else
printf("内存空间不够\n");
}
system(“cls”);清屏函数,在使用前先清下屏,要不之前展示的东西一直放在那,看的不舒服。
if,else语句先判断,我们刚才已经设置好了SIZE,就是通讯录能装的联系人信息的最大值,size是说明当前通讯录里成员的数量。
几个printf,scanf就是把你输入的信息放到struct Contact_Person结构体里。
con->size++;每添加一个联系人,size的大小就增加一个
我们看一下效果:
这样我们就已经把信息录入进去了。
4.3显示联系人信息Show_Contact
void Show_Contact(struct Contact* con)
{
system("cls");
printf(" %-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < con->size; i++)
{
printf("%d. %-20s%-8s%-12s%-15s\n",
i + 1,
con->data[i].name,
con->data[i].sex,
con->data[i].phone,
con->data[i].location
);
}
}
就是把我们之前录入的练习人信息显示出来。
用for循环实现,总共size个成员所以循环size次。
-20s%,打印字符串并且左对齐20位
我们看效果:(信息我提前添加好了几个,后面用的信息都是这几个)
4.3查找联系人Find_Peo
//查找联系人,返回他的序号,如果没有找到返回-1
static int Find_Peo(struct Contact* con, char name[NAME])
{
int i = 0;
for (i = 0; i < con->size; i++)
{
if (0 == strcmp(con->data[i].name, name))
return i;
}
return -1;
}
这是我们在调用一些函数所用到的函数,比如删除练习人这个函数,我们要找到这个联系人才能删除。所以我们把查找联系人这个函数单独拿出来了,因为在main函数那里用不到这个函数,我们就在前面加上static,把他”保护“起来。其他文件就看不到它,也用不了它了。
我们通过输入联系人的名字来判断它是否存在
所有用for循环,把通讯录里的成员一个一个的对比,如果找到了,就把当前的i值返回出去,也可以理解为把这个成员对应的序列信息返回去了。
如果都遍历完了,就返回-1,说明没找到这个联系人
4.4删除指定联系人信息Delete_Contact
void Delete_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要删除的联系人的姓名:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
int i = 0;
if (number != -1)
{
for (i = number; i < con->size - 1; i++)
{
con->data[i] = con->data[i + 1];
}
con->size--;
}
else
printf("找不到联系人\n");
}
在删除之前,先把现有的联系人信息展示出来,这样你就更容易找了。
输入想删除联系人的名字,传到函数Find_Peo里面,返回的值就是这个联系人对应的序号。
我们删除的原理就是,把需要删除的成员被它后面那一个成员的信息覆盖掉。
假设有几个成员1,2,3,4,5.此时我们想删掉2,就把3的信息赋值给2,4赋值给3,5赋值给4。这样就相当于把2删掉啦。
删掉之后记得size–,因为我们通讯录里的成员少了一个
我们看效果:
删完之后在显示一下
4.5查找联系人
void Find_Contact(struct Contact* con)
{
system("cls");
printf("请输入需要查找的联系人的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("%-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
printf("%-20s%-8s%-12s%-15s\n",
con->data[number].name,
con->data[number].sex,
con->data[number].phone,
con->data[number].location
);
}
else
printf("找不到联系人\n");
}
查找也需要用的Find_Peo函数,上面这个查找的代码高级一些,Find_Peo是说明要找的人是否存在,并且返回这个联系人的序号。上面这个函数就是把找到的联系人的信息打印出来
我们看效果:
这就找到了,并且展示出来。
4.6修改联系人信息
void Amend_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要修改联系人信息的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("请输入联系人名字:");
scanf("%s", con->data[number].name);
printf("请输入联系人性别:");
scanf("%s", con->data[number].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[number].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[number].location);
}
else
printf("找不到联系人\n");
}
和删除联系人信息那块代码差别不大
先定位到要修改的联系人的位置,也就是对应的序号,然后重新输入,把之前的信息覆盖掉就行。
我们看效果:
修改为在显示一下
4.7排序联系人信息
static int Com_Name(const void* e1, const void* e2)
{
return strcmp(((struct Contact_Person*)e1)->name, ((struct Contact_Person*)e2)->name);
}
//排序联系人信息
void Sort_Contact(struct Contact* con)
{
system("cls");
qsort(con->data, con->size, sizeof(struct Contact_Person), Com_Name);
Show_Contact(con);
}
这里主要帮忙让你们学习一些qsort函数的用法
qsort函数
void qsort (void* base, size_t num, size_t size,
int (compar)(const void,const void*));
base:需要排序的数组的地址
num:数组中需要排序的元素个数
size:数组中每个元素的大小(单位是字节)
int (compar)(const void,const void*)
是需要我们自己写的函数,在传参的时候,把我们写的函数的函数名传进去就行.
我们要写的函数,返回值是int,参数是两个const void*类型的
这个函数是用来比较两个元素的大小
如果第一个参数>第二个参数返回大于0的数
如果第一个参数<第二个参数返回大于0的数
如果第一个参数=第二个参数返回等于0的数
具体qsort函数怎么使用这个函数,我们现在可以不用管,如果感兴趣可以看看我的其它文章:指针(二)
在这里我们通过名字来进行排序,就是说数组dat里的成员,按照name来排序。每个成员都是一个结构体,我们使用strcmp函数来判断结构体中name的大小。因为strcmp的返回值和我们需要的返回值是一样的。所以直接返回就行
因为我们比较的两个元素都是结构体,所有先把e1,e2强制类型转换成struct Contact_Person*的类型,然后通过它找到结构体name,最后在进行比较。
我们看结果(为了使效果明显,我加了几个成员)
这是没排序之前:
排序后:
按照姓名首字母l<w<z从小到大排好了。
五.代码
想直接用的,复制就行
5.1text.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("****************************************\n");
printf("******** 1.添加 2.删除 ********\n");
printf("******** 3.全部删除 4.修改 ********\n");
printf("******** 5.查找 6.显示 ********\n");
printf("******** 7.排序 0.退出 ********\n");
printf("****************************************\n");
}
int main()
{
int input = 0;
struct Contact con;
//初始化通讯录信息
Init_Contact(&con);
do
{
menu();
printf("请输入->");
scanf("%d", &input);
switch (input)
{
case ADD:
Add_contact(&con);
break;
case DELETE:
Delete_Contact(&con);
break;
case DELETE_ALL:
Init_Contact(&con);
break;
case AMEND:
Amend_Contact(&con);
break;
case FIND:
Find_Contact(&con);
break;
case SHOW:
Show_Contact(&con);
break;
case SORT:
Sort_Contact(&con);
break;
case EXIT:
break;
default:
printf("输入错误,请重新输入->\n");
break;
}
} while (input);
return 0;
}
5.2contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//初始化通讯录信息
void Init_Contact(struct Contact* con)
{
con->size = 0;
memset(con->data, 0, sizeof(con->data));
}
//添加联系人信息
void Add_contact(struct Contact* con)
{
system("cls");
if (con->size < SIZE)
{
printf("请输入联系人名字:");
scanf("%s", con->data[con->size].name);
printf("请输入联系人性别:");
scanf("%s", con->data[con->size].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[con->size].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[con->size].location);
con->size++;
}
else
printf("内存空间不够\n");
}
//显示所有联系人信息
void Show_Contact(struct Contact* con)
{
system("cls");
printf(" %-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < con->size; i++)
{
printf("%d. %-20s%-8s%-12s%-15s\n",
i + 1,
con->data[i].name,
con->data[i].sex,
con->data[i].phone,
con->data[i].location
);
}
}
//查找联系人,返回他的序号,如果没有找到返回-1
static int Find_Peo(struct Contact* con, char name[NAME])
{
int i = 0;
for (i = 0; i < con->size; i++)
{
if (0 == strcmp(con->data[i].name, name))
return i;
}
return -1;
}
//删除指定联系人信息
void Delete_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要删除的联系人的姓名:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
int i = 0;
if (number != -1)
{
for (i = number; i < con->size - 1; i++)
{
con->data[i] = con->data[i + 1];
}
con->size--;
}
else
printf("找不到联系人\n");
}
//查找联系人
void Find_Contact(struct Contact* con)
{
system("cls");
printf("请输入需要查找的联系人的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("%-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
printf("%-20s%-8s%-12s%-15s\n",
con->data[number].name,
con->data[number].sex,
con->data[number].phone,
con->data[number].location
);
}
else
printf("找不到联系人\n");
}
//修改联系人信息
void Amend_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要修改联系人信息的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("请输入联系人名字:");
scanf("%s", con->data[number].name);
printf("请输入联系人性别:");
scanf("%s", con->data[number].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[number].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[number].location);
}
else
printf("找不到联系人\n");
}
static int Com_Name(const void* e1, const void* e2)
{
return strcmp(((struct Contact_Person*)e1)->name, ((struct Contact_Person*)e2)->name);
}
//排序联系人信息
void Sort_Contact(struct Contact* con)
{
system("cls");
qsort(con->data, con->size, sizeof(struct Contact_Person), Com_Name);
Show_Contact(con);
}
5.3contact.h
#pragma once
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10 //通讯录的大小,能装10个成员的信息
#define NAME 20 //联系人名字数组的长度
#define SEX 8 //联系人性别数组的长度
#define PHONE 12 //联系人电话数组的长度
#define LOCATION 15 //联系人地址数组的长度
enum catalog
{
EXIT, //退出
ADD, //添加联系人信息
DELETE, //删除联系人信息
DELETE_ALL,//删除所有人信息
AMEND, //修改联系人信息
FIND, //查找联系人
SHOW, //显示所有联系人信息
SORT, //排序联系人信息
};
//联系人信息
struct Contact_Person
{
char name[NAME]; //联系人姓名
char sex[SEX]; //联系人性别
char phone[PHONE]; //联系人电话
char location[LOCATION]; //联系人地址
};
//通讯录
struct Contact
{
int size;
struct Contact_Person data[SIZE];
};
//初始化通讯录信息
void Init_Contact(struct Contact* con);
//添加联系人信息
void Add_contact(struct Contact* con);
//显示所有联系人信息
void Show_Contact(struct Contact* con);
//删除指定联系人信息
void Delete_Contact(struct Contact* con);
//查找联系人
void Find_Contact(struct Contact* con);
//修改联系人信息
void Amend_Contact(struct Contact* con);
//排序联系人信息
void Sort_Contact(struct Contact* con);
C语言实现通讯录(低配版)
文章目录
- 一.准备
- 二.主文件
- 三.contact.h文件
- 3.1需要用到的宏定义,和函数所需的头文件
- 3.2结构体定义
- 3.3函数的声明
- 四.contact.c文件
- 4.1初始化通讯录信息Init_Contact
- 4.2添加联系人信息Add_contact
- 4.3查找联系人Find_Peo
- 4.4删除指定联系人信息Delete_Contact
- 4.5查找联系人
- 4.6修改联系人信息
- 4.7排序联系人信息
- 五.代码
- 5.1text.c
- 5.2contact.c
- 5.3contact.h
一.准备
首先我们要创建三个文件:
1.text.c主文件
2.contact.c文件,这个主要放的是实现通讯录有关的文件
3.contact.h文件,头文件,有函数的声明,结构体定义和一些宏定义
二.主文件
#include "contact.h"
void menu()
{
printf("****************************************\n");
printf("******** 1.添加 2.删除 ********\n");
printf("******** 3.全部删除 4.修改 ********\n");
printf("******** 5.查找 6.显示 ********\n");
printf("******** 7.排序 0.退出 ********\n");
printf("****************************************\n");
}
int main()
{
int input = 0;
struct Contact con;
//定义一个结构体con,结构体信息在contact.h里面
//初始化通讯录信息
Init_Contact(&con);
do
{
menu();
printf("请输入->");
scanf("%d", &input);
switch (input)
{
case ADD:
Add_contact(&con);
break;
case DELETE:
Delete_Contact(&con);
//全部删除就相当于初始化了
break;
case DELETE_ALL:
Init_Contact(&con);
break;
case AMEND:
Amend_Contact(&con);
break;
case FIND:
Find_Contact(&con);
break;
case SHOW:
Show_Contact(&con);
break;
case SORT:
Sort_Contact(&con);
break;
case EXIT:
break;
default:
printf("输入错误,请重新输入->\n");
break;
}
} while (input);
return 0;
}
这个放在主文件里。
main函数的主要框架是do while函数。这样就可以在执行一次循环之后,继续执行我们想要的内容。而不是在执行一次循环之后就退出去。
循环里面是switch语句。我们的通讯录里有8个命令:添加,删除,全部删除,修改,寻找,展示,排序,退出。
EXIT,ADD,DELETE,DELETE_ALL,AMEND,FIND,SHOW,SORT。这些都是枚举变量,是在contact.h里面定义好的。这些变量的值从0开始。
我们通过定义的input变量来控制这些。假设输入1,input的值就是1,对应的就是实现ADD对应的函数。
每个命令都对应这一个函数,这些函数在contact.c文件里实现。
程序一运行肯定要先初始化,初始化的代码放在contact.c文件里。
为了让使用者知道每个命令对应的按键,所以要有目录menu
menu函数自己定义好就行,这个函数比较简单,直接放在main函数上面就行。
#include “contact.h”
因为我们写的大部分参数和一些定义都在contact.h文件里,所以先包含contact.h,代码才能运行。
三.contact.h文件
3.1需要用到的宏定义,和函数所需的头文件
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10 //通讯录的大小,能装10个成员的信息
#define NAME 20 //联系人名字数组的长度
#define SEX 8 //联系人性别数组的长度
#define PHONE 12 //联系人电话数组的长度
#define LOCATION 15 //联系人地址数组的长度
3.2结构体定义
enum catalog
//枚举
{
EXIT, //退出
ADD, //添加联系人信息
DELETE, //删除联系人信息
DELETE_ALL,//删除所有人信息
AMEND, //修改联系人信息
FIND, //查找联系人
SHOW, //显示所有联系人信息
SORT, //排序联系人信息
};
//联系人信息
struct Contact_Person
{
char name[NAME]; //联系人姓名
char sex[SEX]; //联系人性别
char phone[PHONE]; //联系人电话
char location[LOCATION]; //联系人地址
};
//通讯录
struct Contact
{
int size;
struct Contact_Person data[SIZE];
};
主要讲一下结构体struct Contact
size是为了以后函数的使用,记录当前通讯录里联系人的个数。在初始化是size为0.
struct Contact_Person data[SIZE];是一个数组。
数组里有SIZE个成员,SIZE已经在上面宏定义好了,可自己调整大小。就是说通讯录最多能装SIZE个成员。每个成员的类型都是struct Contact_Person类型的。
struct Contact_Person是我们定义好的结构体。
总结一下:
我们把每个联系人的信息:姓名,性别,手机号,地址封装在一个结构体(struct Contact_Person)里。
然后我们在定义一个更大的结构体里面有成员size,是为了记录当前成员的个数。还有一个成员是一个数组,数组的每个成员都是struct Contact_Person类型的。也就是数组里的每个元素都是一个联系人的信息。
3.3函数的声明
//初始化通讯录信息
void Init_Contact(struct Contact* con);
//添加联系人信息
void Add_contact(struct Contact* con);
//显示所有联系人信息
void Show_Contact(struct Contact* con);
//删除指定联系人信息
void Delete_Contact(struct Contact* con);
//查找联系人
void Find_Contact(struct Contact* con);
//修改联系人信息
void Amend_Contact(struct Contact* con);
//排序联系人信息
void Sort_Contact(struct Contact* con);
这些就是我们在contact.c文件用到的函数
四.contact.c文件
4.1初始化通讯录信息Init_Contact
void Init_Contact(struct Contact* con)
{
con->size = 0;
memset(con->data, 0, sizeof(con->data));
}
我们将结构体里的size设置为0,说明此时通讯录里还没有成员
memset函数:
将结构体data数组里面的数据全部设置成0。
memset函数的用法:
void * memset ( void * ptr, int value, size_t num );
ptr:需要更改(填充)数据的内存块的地址,上面我们要更改的是数组data。
value:我们要把这个内存块的内容更改成value,上面我们要把数组里的内容变成0
size_t num:我们要把这个内存块的num个字节的内容改成value。上面我们用到的是sizeof(con->data),就是把整个数组大小的内容设置成0.这样就达到初始话的效果了。
4.2添加联系人信息Add_contact
void Add_contact(struct Contact* con)
{
system("cls");
if (con->size < SIZE)
{
printf("请输入联系人名字:");
scanf("%s", con->data[con->size].name);
printf("请输入联系人性别:");
scanf("%s", con->data[con->size].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[con->size].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[con->size].location);
con->size++;
}
else
printf("内存空间不够\n");
}
system(“cls”);清屏函数,在使用前先清下屏,要不之前展示的东西一直放在那,看的不舒服。
if,else语句先判断,我们刚才已经设置好了SIZE,就是通讯录能装的联系人信息的最大值,size是说明当前通讯录里成员的数量。
几个printf,scanf就是把你输入的信息放到struct Contact_Person结构体里。
con->size++;每添加一个联系人,size的大小就增加一个
我们看一下效果:
这样我们就已经把信息录入进去了。
4.3显示联系人信息Show_Contact
void Show_Contact(struct Contact* con)
{
system("cls");
printf(" %-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < con->size; i++)
{
printf("%d. %-20s%-8s%-12s%-15s\n",
i + 1,
con->data[i].name,
con->data[i].sex,
con->data[i].phone,
con->data[i].location
);
}
}
就是把我们之前录入的练习人信息显示出来。
用for循环实现,总共size个成员所以循环size次。
-20s%,打印字符串并且左对齐20位
我们看效果:(信息我提前添加好了几个,后面用的信息都是这几个)
4.3查找联系人Find_Peo
//查找联系人,返回他的序号,如果没有找到返回-1
static int Find_Peo(struct Contact* con, char name[NAME])
{
int i = 0;
for (i = 0; i < con->size; i++)
{
if (0 == strcmp(con->data[i].name, name))
return i;
}
return -1;
}
这是我们在调用一些函数所用到的函数,比如删除练习人这个函数,我们要找到这个联系人才能删除。所以我们把查找联系人这个函数单独拿出来了,因为在main函数那里用不到这个函数,我们就在前面加上static,把他”保护“起来。其他文件就看不到它,也用不了它了。
我们通过输入联系人的名字来判断它是否存在
所有用for循环,把通讯录里的成员一个一个的对比,如果找到了,就把当前的i值返回出去,也可以理解为把这个成员对应的序列信息返回去了。
如果都遍历完了,就返回-1,说明没找到这个联系人
4.4删除指定联系人信息Delete_Contact
void Delete_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要删除的联系人的姓名:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
int i = 0;
if (number != -1)
{
for (i = number; i < con->size - 1; i++)
{
con->data[i] = con->data[i + 1];
}
con->size--;
}
else
printf("找不到联系人\n");
}
在删除之前,先把现有的联系人信息展示出来,这样你就更容易找了。
输入想删除联系人的名字,传到函数Find_Peo里面,返回的值就是这个联系人对应的序号。
我们删除的原理就是,把需要删除的成员被它后面那一个成员的信息覆盖掉。
假设有几个成员1,2,3,4,5.此时我们想删掉2,就把3的信息赋值给2,4赋值给3,5赋值给4。这样就相当于把2删掉啦。
删掉之后记得size–,因为我们通讯录里的成员少了一个
我们看效果:
删完之后在显示一下
4.5查找联系人
void Find_Contact(struct Contact* con)
{
system("cls");
printf("请输入需要查找的联系人的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("%-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
printf("%-20s%-8s%-12s%-15s\n",
con->data[number].name,
con->data[number].sex,
con->data[number].phone,
con->data[number].location
);
}
else
printf("找不到联系人\n");
}
查找也需要用的Find_Peo函数,上面这个查找的代码高级一些,Find_Peo是说明要找的人是否存在,并且返回这个联系人的序号。上面这个函数就是把找到的联系人的信息打印出来
我们看效果:
这就找到了,并且展示出来。
4.6修改联系人信息
void Amend_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要修改联系人信息的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("请输入联系人名字:");
scanf("%s", con->data[number].name);
printf("请输入联系人性别:");
scanf("%s", con->data[number].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[number].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[number].location);
}
else
printf("找不到联系人\n");
}
和删除联系人信息那块代码差别不大
先定位到要修改的联系人的位置,也就是对应的序号,然后重新输入,把之前的信息覆盖掉就行。
我们看效果:
修改为在显示一下
4.7排序联系人信息
static int Com_Name(const void* e1, const void* e2)
{
return strcmp(((struct Contact_Person*)e1)->name, ((struct Contact_Person*)e2)->name);
}
//排序联系人信息
void Sort_Contact(struct Contact* con)
{
system("cls");
qsort(con->data, con->size, sizeof(struct Contact_Person), Com_Name);
Show_Contact(con);
}
这里主要帮忙让你们学习一些qsort函数的用法
qsort函数
void qsort (void* base, size_t num, size_t size,
int (compar)(const void,const void*));
base:需要排序的数组的地址
num:数组中需要排序的元素个数
size:数组中每个元素的大小(单位是字节)
int (compar)(const void,const void*)
是需要我们自己写的函数,在传参的时候,把我们写的函数的函数名传进去就行.
我们要写的函数,返回值是int,参数是两个const void*类型的
这个函数是用来比较两个元素的大小
如果第一个参数>第二个参数返回大于0的数
如果第一个参数<第二个参数返回大于0的数
如果第一个参数=第二个参数返回等于0的数
具体qsort函数怎么使用这个函数,我们现在可以不用管,如果感兴趣可以看看我的其它文章:指针(二)
在这里我们通过名字来进行排序,就是说数组dat里的成员,按照name来排序。每个成员都是一个结构体,我们使用strcmp函数来判断结构体中name的大小。因为strcmp的返回值和我们需要的返回值是一样的。所以直接返回就行
因为我们比较的两个元素都是结构体,所有先把e1,e2强制类型转换成struct Contact_Person*的类型,然后通过它找到结构体name,最后在进行比较。
我们看结果(为了使效果明显,我加了几个成员)
这是没排序之前:
排序后:
按照姓名首字母l<w<z从小到大排好了。
五.代码
想直接用的,复制就行
5.1text.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("****************************************\n");
printf("******** 1.添加 2.删除 ********\n");
printf("******** 3.全部删除 4.修改 ********\n");
printf("******** 5.查找 6.显示 ********\n");
printf("******** 7.排序 0.退出 ********\n");
printf("****************************************\n");
}
int main()
{
int input = 0;
struct Contact con;
//初始化通讯录信息
Init_Contact(&con);
do
{
menu();
printf("请输入->");
scanf("%d", &input);
switch (input)
{
case ADD:
Add_contact(&con);
break;
case DELETE:
Delete_Contact(&con);
break;
case DELETE_ALL:
Init_Contact(&con);
break;
case AMEND:
Amend_Contact(&con);
break;
case FIND:
Find_Contact(&con);
break;
case SHOW:
Show_Contact(&con);
break;
case SORT:
Sort_Contact(&con);
break;
case EXIT:
break;
default:
printf("输入错误,请重新输入->\n");
break;
}
} while (input);
return 0;
}
5.2contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//初始化通讯录信息
void Init_Contact(struct Contact* con)
{
con->size = 0;
memset(con->data, 0, sizeof(con->data));
}
//添加联系人信息
void Add_contact(struct Contact* con)
{
system("cls");
if (con->size < SIZE)
{
printf("请输入联系人名字:");
scanf("%s", con->data[con->size].name);
printf("请输入联系人性别:");
scanf("%s", con->data[con->size].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[con->size].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[con->size].location);
con->size++;
}
else
printf("内存空间不够\n");
}
//显示所有联系人信息
void Show_Contact(struct Contact* con)
{
system("cls");
printf(" %-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < con->size; i++)
{
printf("%d. %-20s%-8s%-12s%-15s\n",
i + 1,
con->data[i].name,
con->data[i].sex,
con->data[i].phone,
con->data[i].location
);
}
}
//查找联系人,返回他的序号,如果没有找到返回-1
static int Find_Peo(struct Contact* con, char name[NAME])
{
int i = 0;
for (i = 0; i < con->size; i++)
{
if (0 == strcmp(con->data[i].name, name))
return i;
}
return -1;
}
//删除指定联系人信息
void Delete_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要删除的联系人的姓名:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
int i = 0;
if (number != -1)
{
for (i = number; i < con->size - 1; i++)
{
con->data[i] = con->data[i + 1];
}
con->size--;
}
else
printf("找不到联系人\n");
}
//查找联系人
void Find_Contact(struct Contact* con)
{
system("cls");
printf("请输入需要查找的联系人的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("%-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
printf("%-20s%-8s%-12s%-15s\n",
con->data[number].name,
con->data[number].sex,
con->data[number].phone,
con->data[number].location
);
}
else
printf("找不到联系人\n");
}
//修改联系人信息
void Amend_Contact(struct Contact* con)
{
system("cls");
Show_Contact(con);
printf("请输入需要修改联系人信息的名字:");
char name[NAME];
scanf("%s", name);
int number = 0;
number = Find_Peo(con, name);
if (number != -1)
{
printf("请输入联系人名字:");
scanf("%s", con->data[number].name);
printf("请输入联系人性别:");
scanf("%s", con->data[number].sex);
printf("请输入联系人电话:");
scanf("%s", con->data[number].phone);
printf("请输入联系人地址:");
scanf("%s", con->data[number].location);
}
else
printf("找不到联系人\n");
}
static int Com_Name(const void* e1, const void* e2)
{
return strcmp(((struct Contact_Person*)e1)->name, ((struct Contact_Person*)e2)->name);
}
//排序联系人信息
void Sort_Contact(struct Contact* con)
{
system("cls");
qsort(con->data, con->size, sizeof(struct Contact_Person), Com_Name);
Show_Contact(con);
}
5.3contact.h
#pragma once
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10 //通讯录的大小,能装10个成员的信息
#define NAME 20 //联系人名字数组的长度
#define SEX 8 //联系人性别数组的长度
#define PHONE 12 //联系人电话数组的长度
#define LOCATION 15 //联系人地址数组的长度
enum catalog
{
EXIT, //退出
ADD, //添加联系人信息
DELETE, //删除联系人信息
DELETE_ALL,//删除所有人信息
AMEND, //修改联系人信息
FIND, //查找联系人
SHOW, //显示所有联系人信息
SORT, //排序联系人信息
};
//联系人信息
struct Contact_Person
{
char name[NAME]; //联系人姓名
char sex[SEX]; //联系人性别
char phone[PHONE]; //联系人电话
char location[LOCATION]; //联系人地址
};
//通讯录
struct Contact
{
int size;
struct Contact_Person data[SIZE];
};
//初始化通讯录信息
void Init_Contact(struct Contact* con);
//添加联系人信息
void Add_contact(struct Contact* con);
//显示所有联系人信息
void Show_Contact(struct Contact* con);
//删除指定联系人信息
void Delete_Contact(struct Contact* con);
//查找联系人
void Find_Contact(struct Contact* con);
//修改联系人信息
void Amend_Contact(struct Contact* con);
//排序联系人信息
void Sort_Contact(struct Contact* con);