免责声明:此文章只做本人学习记录使用
目录
分为三个文件contact.h, contact.c 和 test.c,分别作用为:定义函数,实现函数,实现通讯录。
contact.h文件
#include<stdio.h>
#define MAX 1000//定义总个数
#define MAX_NAME 20//名字所占字节数
#define MAX_SEX 10//性别所占字节数
#define MAX_ADD 20//地址所占字节数
struct people//定义每个数据元素的大小
{
char name[MAX_NAME];
char sex[MAX_SEX];
char add[MAX_ADD];
size_t num; //用size_t因为电话号码只有正数
int age;
};
struct contact
{
struct people date[MAX];
int size;//定义size,确定是第几个数据对象
};
enum elect//位段,定义各模式代表的数字
{
EXIT,
ADD,
MODIFY,
SHOW,
DEL,
SEARCH,
SORT,
};
//初始化列表函数
void Initcontact(struct contact* p1);
//添加函数
void AddContact(struct contact* p1);
//查看函数
void ShowContact(const struct contact* p1);
//删除函数
void DelComtact(struct contact* p1);
//搜索函数
void SearcahContact(struct contact*p1);
//修改函数
void ModifyContact(struct contact *p1);
//排序函数
void SortContact(struct contact *p1 );
contact.c文件
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include"contact.h"//要用双引号
static void sorts(struct contact *p1,int j)//排序的交换函数
{
struct people c = { 0 };
c = p1->date[j];
p1->date[j] = p1->date[j + 1];
p1->date[j + 1] = c;
}
static void bubble_sort_by_num(struct contact* p1,int sz)//通过电话大小排序
{
int i = 0;
for (i = 0; i < sz; i++)//冒泡
{
int j = 0;
for (j = 0; j < sz - i; j++)
{
if ((p1->date[j].num - p1->date[j + 1].num) > 1)
{
sorts(p1, j);//交换函数
}
}
}
}
static void bubble_sort_by_age(struct contact*p1,int sz)//通过年龄大小排序
{
int i = 0;
for (i = 0; i < sz; i++)//冒泡
{
int j = 0;
for (j = 0; j < sz - i; j++)
{
if (p1->date[j].age - p1->date[j + 1].age >1)
{
sorts(p1, j);
}
}
}
}
static void bubble_sort_by_let(struct contact*p1,int sz)//通过名字排序
{
int i = 0;
for (i = 0; i < sz; i++)//冒泡
{
int j = 0;
for (j = 0; j < sz - i; j++)
{
if (my_strcmp(p1->date[j].name,p1->date[j+1].name)== 1)
{
sorts(p1, j);
}
}
}
}
static int my_strcmp(const char* str1, const char* str2)//字母比较函数(可以用strcmp代替)
{
assert(str1 && str2);//为了保证str1和str2不是空
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
//return (*str1-str2);
if (*str1 > *str2)
return 1;//不一定是1,只要是大于0的数都可以
else
return -1;//不一定是-1,只要是小于0的数都可以
}
static int Findbyname(const struct contact*p1)
//为了避免函数冗余单独把输入名字和遍历数据,拿了出来
{
char name[MAX_NAME] = { 0 };
printf("请输入要查找的名字");
scanf_s("%s", &name,MAX_NAME);
int i = 0;
for (i = 0; i < p1->size; i++)
{
if (0 == my_strcmp(name, p1->date[i].name))
{
return i;
}
}
if (i == p1->size)
{
return -1;
}
}
void Initcontact(struct contact* p1)//初始化函数
{
memset(p1->date, 0, sizeof(p1->date));
p1->size = 0;//都设置为0
}
void AddContact(struct contact* p1)//添加函数
{
if (p1->size == MAX)//size的作用
{
printf("内存已满\n");
}
else//添加各元素的数据
{
printf("请输入名字\n");
scanf_s("%s", p1->date[p1->size].name,MAX_NAME);
printf("请输入性别\n");
scanf_s("%s", p1->date[p1->size].sex,MAX_SEX);
printf("请输入地址\n");
scanf_s("%s", p1->date[p1->size].add,MAX_ADD);
printf("请输入电话\n");
scanf_s("%zu", &(p1->date[p1->size].num));
printf("请输入年龄\n");
scanf_s("%d", &(p1->date[p1->size].age));
p1->size++;
printf("添加成功\n输入0退出\n");
}
}
void ShowContact(const struct contact* p1)//查看函数
{
if (p1->size == 0)
{
printf("通讯录是空\n");
}
else//打印元素时,上面第一行为标题,往下是元素数据
{
int i = 0;
printf("%-20s\t%-10s\t%-16s\t%-20s\t%-5s\n", "名字", "性别", "地址", "电话", "年龄");
for (i = 0; i < p1->size; i++)//为了左对齐所以打‘-’
{
printf("%-20s\t%-10s\t%-16s\t%-2zu\t%-d\n",
p1->date[i].name,
p1->date[i].sex,
p1->date[i].add,
p1->date[i].num,
p1->date[i].age);
}
}
}
void DelComtact(struct contact* p1)//删除函数
{
int ret = Findbyname(p1);//通过名字查找
if (p1->size == 0)
{
printf("通讯录是空\n");
}
else if (ret == -1)
{
printf("查无此人\n");
}
else//用覆盖的方法删除元素
{
int j = 0;
for (j = ret; j < p1->size-1; j++)
{
p1->date[j] = p1->date[j + 1];
}
printf("已删除\n");
}
p1->size--;
}
void SearcahContact(struct contact* p1)
{
int ret = Findbyname(p1);//通过名字查找
if (ret == -1)
{
printf("查无此人\n");
}
else
{
printf("%-20s\t%-10s\t%-16s\t%-20s\t%-5s\n", "名字", "性别", "地址", "电话", "年龄");
printf("%-20s\t%-10s\t%016s\t%-2zu\t%-2d\n",
p1->date[ret].name,
p1->date[ret].sex,
p1->date[ret].add,
p1->date[ret].num,
p1->date[ret].age);
}
}
void ModifyContact(struct contact* p1)//修改函数
{
int ret = Findbyname(p1);//通过名字查找
if (p1->size == 0)
{
printf("通讯录是空\n");
}
else if (ret == -1)
{
printf("查无此人\n");
}
else
{
printf("请输入名字\n");
scanf_s("%s", p1->date[ret].name,MAX_NAME);
printf("请输入性别\n");
scanf_s("%s", p1->date[ret].sex,MAX_SEX);
printf("请输入地址\n");
scanf_s("%s", p1->date[ret].add,MAX_ADD);
printf("请输入电话\n");
scanf_s("%zu", &(p1->date[ret].num));
printf("请输入年龄\n");
scanf_s("%d", &(p1->date[ret].age));
p1->size++;
printf("添加成功,输入0退出\n");
}
}
void SortContact(struct contact*p1)//排序函数
{
printf("按照姓名字母排序输入‘1’\n");
printf("按照电话号码排序输入‘2’\n");
printf("按照年龄排序输入‘3’\n");
int i = 0;
scanf_s("%d",&i,8);
if (p1->size ==0)
{
printf("通讯录是空\n");
}
else if (i == 1)
{
bubble_sort_by_let(p1,p1->size);
printf("排序成功\n");
}
else if(i==2)
{
bubble_sort_by_num(p1,p1->size);
printf("排序成功\n");
}
else
{
bubble_sort_by_age(p1, p1->size);
printf("排序成功\n");
}
}
test.c文件
#include<string.h>
#include<stdio.h>
#include"contact.h"
void mune()//菜单打印
{
printf("************************************\n");
printf("************************************\n");
printf("***** 1.添加 2.修改 *********\n");
printf("***** 3.查看 4.删除 *********\n");
printf("***** 5.搜索 6.排序 *********\n");
printf("***** 0.退出 *********\n");
printf("************************************\n");
}
void ExitContact()//退出的函数
{
printf("已退出");
}
int main()
{
int n = 0;
struct contact con;//只有一个con,里面有max个date
Initcontact(&con);//初始化
do
{
mune();
printf("请选择模式(输入数字)");
scanf_s("%d", &n);//模式的选择
//int* arr[7] = {ExitContact,AddContact,ModifyContact,ShowContact,DelContact,SearchContact,
//SortContact,};
switch (n)//利用位段,把选择函数变成选择数字
{
case(ADD):
AddContact(&con);
break;
case(MODIFY):
ModifyContact(&con);
break;
case(SHOW):
ShowContact(&con);
break;
case(DEL):
DelComtact(&con);
break;
case(SEARCH):
SearcahContact(&con);
break;
case(SORT):
SortContact(&con);
break;
case(EXIT):
ExitContact();
break;
default:
printf("请输入正确的数字");
}
} while (n);//输入0就退出
return 0;
}