1.框架构造
首先,为了构造一个通讯录,我们定义一个结构体peoinfo存放每个人的信息:
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 20
struct peoinfo//定义一个结构体保存一个人的信息
{
char name[NAME_MAX];//姓名
int age;//年龄
char sex[SEX_MAX];//性别
char tele[TELE_MAX];//电话
char addr[ADDR_MAX];//住址
};
这里我们不直接定义每个数组的具体大小,而是使用宏定义(define)来定义每个数组的大小,以便日后需要修改的时候,直接修改宏即可,而不需要对每个变量进行修改,增加了代码的可维护性。
每个人的信息定义了一个结构体,但是信息需要存放到一块吧?并且,除了每个人的信息以外,我们还需要知道当前通讯录里包含了几个人的信息,以方便我们对通讯录进行?操作。所以我们再定义一个结构体contact,成员包括所有人的信息以及当前通讯录里有几个人的信息:
#define MAX 1000//使用宏进行处理,方便修改通讯录大小
struct contact//创建一个结构体,用于保存一整个通讯录的信息
{
struct peoinfo data[MAX];//定义类型为struct peoinfo的数组,元素数量为MAX
int size;//用于保存当前通讯录的个人信息数量
};
我们想一想一个通讯录需要有哪些功能呢?除了增加信息,删除信息,查找信息,修改信息。还有比如排序,清空,显示通讯录的功能。我们先构造一个meun函数打印一个菜单,使用户可以清楚的知道自己可以进行哪些操作。到了用户操作的部分,我们使用do while语句进行循环,使用户可以对通讯录进行重复操作。接下来,在do while语句内嵌一个switch语句,使用户可以通过输入数字来进行不同的操作。
void menu()
{
printf("*******************************\n");
printf("*** 1.add 2.del ***\n");
printf("*** 3.search 4.modify ***\n");
printf("*** 5.sort 6.show ***\n");
printf("*** 7.empty 0.exit ***\n");
printf("*******************************\n");
}
enum//使用枚举类型,增加代码的可读性
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
SHOW,
EMPTY
};
int main()
{
struct contact con;//创建一个通讯录
InitCon(&con);//初始化通讯录
int choose = 0;//定义一个变量记录用户在菜单界面的输入
do {
menu();//打印菜单
printf("请输入:");
scanf("%d", &choose);
switch (choose)
{
case ADD://增加
AddCon(&con);
break;
case DEL://删除
DelCon(&con);
break;
case SEARCH://查找
SearchCon(&con);
break;
case MODIFY://修改
ModifyCon(&con);
break;
case SORT://排序
SortCon(&con);
break;
case SHOW://显示
ShowCon(&con);
break;
case EXIT://退出
printf("退出通讯录。");
break;
case EMPTY://清空
EmptyCon(&con);
break;
default://如果没有输入以上数字,告诉用户输入错误
printf("输入错误,请重新输入\n");
break;
}
} while (choose);//当用户输入0时跳出循环
return 0;
}
?之后,我们就要完成各个不同的功能啦。
2.函数实现
初始化函数InitCon
首先要完成的就是对通讯录的初始化,在初始化前先进行断言,确定传入的指针不是空指针。在初始化函数InitCon内我们使用memset函数直接对内存进行初始化。memset的三个参数分别为目标空间的起始地址,目标空间初始化为什么值,以及要初始化的字节数量。所以我们向初始化函数内传入结构体指针,作为memset函数的第一个参数。之后,我们将目标空间初始化为0,所以第二个参数为0,最后,利用sizeof操作符,得到struct contact结构体的大小。虽然size已经被置为0,为了后续修改,我们仍对size进行初始化。
void InitCon(struct contact* con)
{
assert(con);//断言
memset(con, 0, sizeof(struct contact));//初始化
con->size=0;//size初始化
}
增加联系人函数AddCon
接下来要完成的是增加联系人,首先进行断言确保con不是空指针,其次判断通讯录是否已满,已满则提示用户并且直接return退出函数。没有问题的话就让用户进行输入,并且存放数据。
这里解释一下为什么将数据存放到con->data[con->size].name。当通讯录没有联系人时,size=0,这时候con->data[con->size]就指向了data数组中的第一个元素(结构体struct peoinfo),最后进行.name操作,指向了data数组第一块空间的name成员处。增加n个联系人后,size=n,这样con->data[con->size]就指向了data数组的第n+1个元素。就可以在第n个联系人后面新增一个联系人。
?
void AddCon(struct contact* con)//增加
{
assert(con);//断言,确保con不是空指针
if (con->size == MAX)//如果通讯录已满,提醒用户并且不让用户再增加
{
printf("通讯录已满.\n");
return;
}
printf("请输入名字:");
scanf("%s", con->data[con->size].name);
printf("请输入年龄:");
scanf("%d", &con->data[con->size].age);
printf("请输入性别:");
scanf("%s", con->data[con->size].sex);
printf("请输入电话:");
scanf("%s", con->data[con->size].tele);
printf("请输入地址:");
scanf("%s", con->data[con->size].addr);
printf("添加联系人成功。\n");
con->size++;//记得要让size增加,以记录当前的联系人数量
}
删除联系人函数DelCon
首先进行断言,并且判断通讯录是否为空,若为空则直接return。然后我们对联系人进行查找,这里我们构造一个函数FindCon,实现输入联系人名字并且进行查找的功能,若查找到联系人则返回该联系人信息的下标,若没有找到则返回-1。FindCon函数的实现我们在实现DelCon函数之后完成。在得到返回值后,我们对返回值进行判断,若为-1则提示没有找到并且return。否则就通过将删除位置开始的数据整体向前移动一位达到删除的目的。注意这里删除数据要从低位向高位进行,否则会覆盖数据。这里我们拿一个数组举例。
覆盖掉数据后,我们将size的大小减一,这样就完成了对联系人的删除。?
void DelCon(struct contact* con)//删除
{
assert(con);//断言
if (!con->size)//通讯录为空时,不允许删除
{
printf("通讯录为空,无法删除联系人。\n");
return;
}
int i=FindCon(con);//创建一个搜寻联系人函数
if (i == -1)//当搜寻联系人函数返回-1,说明没有查找到该联系人
{
printf("没有找到该联系人。\n");
return;
}
while ( i< con->size - 1)//将数据从后往前移动,覆盖住要删除的联系人
con->data[i++] = con->data[i + 1];
con->size--;//联系人数量size减1
printf("删除联系人成功\n");
}
?搜寻联系人函数FindCon
遍历整个通讯录,在循环内判断联系人的名字与用户输入的名字是否相同,若相同则返回下标,当遍历结束,说明没有找到,返回-1。
int FindCon(struct contact* con)
{
assert(con);//断言
printf("请输入联系人的名字:");
char name[NAME_MAX] = { 0 };
scanf("%s", name);
int i = 0;
for (i = 0; i < con->size; i++)//遍历通讯录
{
if (!strcmp(con->data[i].name, name))//使用strcmp函数进行判断
{ //若返回0则说明找到了联系人
return i;//找到了就返回联系人对应的下标
}
}
return -1;//循环结束说明没有找到 返回-1
}
?查找联系人函数SearchCon
照常断言以及判断通讯录是否为空,判断后使用搜寻函数查找联系人,当返回值不为-1,打印找到的联系人信息。
void SearchCon(struct contact* con)
{
assert(con);//断言
if (!con->size)//判断通讯录是否为空
{
printf("通讯录为空,无法查找联系人。\n");
return;
}
int i=FindCon(con);//使用搜寻函数查找联系人
if (i == -1)//返回-1则说明没有找到联系人
{
printf("没有找到该联系人。\n");
return;
}
//输出联系人信息
printf("%15s%10s%10s%15s%20s\n", "姓名", "年龄", "性别", "电话", "住址");
printf("%15s%10d%10s%15s%20s\n",
con->data[i].name,
con->data[i].age,
con->data[i].sex,
con->data[i].tele,
con->data[i].addr);
}
?修改联系人信息函数ModifyCon
先进行断言以及通讯录是否为空的判断,再使用搜寻函数查找联系人,查找成功后,利用switch case语句判断要修改联系人的哪个信息,再针对该信息进行修改。
void ModifyCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空,无法修改联系人。\n");
return;
}
int i = FindCon(con);
if (i == -1)
{
printf("没有找到该联系人。\n");
return;
}
printf("请输入要修改哪个信息:1:姓名, 2:年龄, 3:性别, 4:电话, 5:住址\n");
int a = 0;
scanf("%d", &a);
switch (a)
{
case 1:
printf("请输入修改后的姓名:");
scanf("%s", &con->data[i].name);
break;
case 2:
printf("请输入修改后的年龄:");
scanf("%d", &con->data[i].age);
break;
case 3:
printf("请输入修改后的性别:");
scanf("%s", con->data[i].sex);
break;
case 4:
printf("请输入修改后的电话:");
scanf("%s", con->data[i].tele);
break;
case 5:
printf("请输入修改后的地址:");
scanf("%s", con->data[i].addr);
break;
default:
printf("输入错误。\n");
return;
}
printf("修改联系人成功。\n");
}
?排序函数SortCon
这里我们介绍按名字进行排序。
先断言并且判断通讯录是否为空,然后用冒泡排序算法对通讯录进行排序。
void SortCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空。\n");
return;
}
int i = 0;
int j = 0;
struct peoinfo tmp;//为了方便交换信息,构造一个tmp变量
for (i = 0; i < con->size - 1; i++)
{
for (j = 0; j < con->size - i - 1; j++)
{
if (strcmp(con->data[j].name, con->data[j + 1].name)>0)
{//对名字进行判断,若不符合顺序,则交换两个联系人的信息
tmp = con->data[j];
con->data[j] = con->data[j + 1];
con->data[j + 1] = tmp;
}
}
}
printf("排序完成.\n");
}
清空通讯录函数EmptyCon?
先进行断言,再使用初始化函数InitCon将数据清0,同时size也被置为0,就完成了对通讯录的清空。
void EmptyCon(struct contact* con)
{
assert(con);//断言
InitCon(con);//调用初始化函数对通讯录进行清空。
printf("清空通讯录成功.\n");
}
3.源码分享
主函数部分
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
int main()
{
struct contact con;
InitCon(&con);
int choose = 0;
do {
menu();
printf("请输入:");
scanf("%d", &choose);
switch (choose)
{
case ADD:
AddCon(&con);
break;
case DEL:
DelCon(&con);
break;
case SEARCH:
SearchCon(&con);
break;
case MODIFY:
ModifyCon(&con);
break;
case SORT:
SortCon(&con);
break;
case SHOW:
ShowCon(&con);
break;
case EXIT:
printf("退出通讯录。");
break;
case EMPTY:
EmptyCon(&con);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (choose);
return 0;
}
函数实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("*******************************\n");
printf("*** 1.add 2.del ***\n");
printf("*** 3.search 4.modify ***\n");
printf("*** 5.sort 6.show ***\n");
printf("*** 7.empty 0.exit ***\n");
printf("*******************************\n");
}
void InitCon(struct contact* con)
{
assert(con);
memset(con, 0, sizeof(struct contact));
con->size = 0;
}
void AddCon(struct contact* con)
{
assert(con);
if (con->size == MAX)
{
printf("通讯录已满.\n");
return;
}
printf("请输入名字:");
scanf("%s", con->data[con->size].name);
printf("请输入年龄:");
scanf("%d", &con->data[con->size].age);
printf("请输入性别:");
scanf("%s", con->data[con->size].sex);
printf("请输入电话:");
scanf("%s", con->data[con->size].tele);
printf("请输入地址:");
scanf("%s", con->data[con->size].addr);
printf("添加联系人成功。\n");
con->size++;
}
void ShowCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空。\n");
return;
}
printf("%15s%10s%10s%15s%20s\n", "姓名","年龄","性别","电话","住址");
int i = 0;
for (i = 0; i < con->size; i++)
{
printf("%15s%10d%10s%15s%20s\n",
con->data[i].name,
con->data[i].age,
con->data[i].sex,
con->data[i].tele,
con->data[i].addr);
}
}
int FindCon(struct contact* con)
{
assert(con);
printf("请输入联系人的名字:");
char name[NAME_MAX] = { 0 };
scanf("%s", name);
int i = 0;
for (i = 0; i < con->size; i++)
{
if (!strcmp(con->data[i].name, name))
{
return i;
}
}
return -1;
}
void DelCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空,无法删除联系人。\n");
return;
}
int i=FindCon(con);
if (i == -1)
{
printf("没有找到该联系人。\n");
return;
}
while ( i< con->size - 1)
con->data[i++] = con->data[i + 1];
con->size--;
printf("删除联系人成功\n");
}
void SearchCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空,无法查找联系人。\n");
return;
}
int i=FindCon(con);
if (i == -1)
{
printf("没有找到该联系人。\n");
return;
}
printf("%15s%10s%10s%15s%20s\n", "姓名", "年龄", "性别", "电话", "住址");
printf("%15s%10d%10s%15s%20s\n",
con->data[i].name,
con->data[i].age,
con->data[i].sex,
con->data[i].tele,
con->data[i].addr);
}
void ModifyCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空,无法修改联系人。\n");
return;
}
int i = FindCon(con);
if (i == -1)
{
printf("没有找到该联系人。\n");
return;
}
printf("请输入要修改哪个信息:1:姓名, 2:年龄, 3:性别, 4:电话, 5:住址\n");
int a = 0;
scanf("%d", &a);
switch (a)
{
case 1:
printf("请输入修改后的姓名:");
scanf("%s", &con->data[i].name);
break;
case 2:
printf("请输入修改后的年龄:");
scanf("%d", &con->data[i].age);
break;
case 3:
printf("请输入修改后的性别:");
scanf("%s", con->data[i].sex);
break;
case 4:
printf("请输入修改后的电话:");
scanf("%s", con->data[i].tele);
break;
case 5:
printf("请输入修改后的地址:");
scanf("%s", con->data[i].addr);
break;
default:
printf("输入错误。\n");
return;
}
printf("修改联系人成功。\n");
}
void SortCon(struct contact* con)
{
assert(con);
if (!con->size)
{
printf("通讯录为空。\n");
return;
}
int i = 0;
int j = 0;
struct peoinfo tmp;
for (i = 0; i < con->size - 1; i++)
{
for (j = 0; j < con->size - i - 1; j++)
{
if (strcmp(con->data[j].name, con->data[j + 1].name) > 0)
{
tmp = con->data[j];
con->data[j] = con->data[j + 1];
con->data[j + 1] = tmp;
}
}
}
printf("排序完成.\n");
}
void EmptyCon(struct contact* con)
{
assert(con);
InitCon(con);
printf("清空通讯录成功.\n");
}
头文件
#pragma once
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 20
#define MAX 1000
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
void menu();
void InitCon(struct contact* con);
void AddCon(struct contact* con);
void ShowCon(struct contact* con);
int FindCon(struct contact* con);
void DelCon(struct contact* con);
void SearchCon(struct contact* con);
void ModifyCon(struct contact* con);
void SortCon(struct contact* con);
void EmptyCon(struct contact* con);
struct peoinfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
};
struct contact
{
struct peoinfo data[MAX];
int size;
};
enum
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
SHOW,
EMPTY
};
|