目录
①通讯录模板
②先使用未定义函数(理想函数功能)填补模板
③定义实现函数
首先,需要两个结构体来支撑,第一个结构体(content,人的属性),第二个结构体(contact_list, 包含属性为,保存的人(数组)和保存的人数)(也可以分装为两个,但是后面传参太麻烦了)
其次,初始化。
然后,do while 实现多次操作(根据操作了什么来确定要不要循环),switch配合,(system(“cls”)为清屏操作,为了美观),其中,每次循环都要打印菜单,根据选项选择操作内容
最后,根据选择的数字,进入不同的函数(添加,删除,寻找,修改,展示,排序,加密,展示秘密,揭秘),还有输入错误,以及循环出口(输入0)
注意:其中case后面的是要自己定义的常数,这样写增加可读性和实际意义。
接下来就是按照自己的意愿去实现函数!(注意先直接“用着”,定好框架,待会儿再实现它)
void test()
{
int input = 0;
struct contact_list total;
struct contact_list extra;
init(&total);
init(&extra);
do
{
menu1();
printf("请做出选择:>");
scanf("%d", &input);
system("cls");
switch (input)
{
case ADD:
add_man(&total);
break;
case DEL:
del_man(&total);
break;
case SEARCH:
search_man(&total);
break;
case MODIFY:
modify_man(&total);
break;
case SHOW:
show_all(&total);
printf("展示成功\n");
break;
case SORT:
sort_all(&total);
break;
case EXIT:
printf("退出成功\n");
break;
case SECRET:
secret(&total,&extra);
break;
case SHOW_SECRET:
show_secret(&total, &extra);
break;
case REMOVE_SECRET:
remove_secret(&total, &extra);
break;
default:
printf("输入错误\n");
break;
}
} while (input);
}
值得一提的是,最好声明和定义和主函数都分别放在不同的文件,声明放在头文件,在源文件中引用(自己写的头文件要用双引号而不是尖括号)
并且在定义函数时,时时刻刻按照思路把需要定义的函数,定义在“此时此刻”的函数的上面一个,这样就不会有一些“未定义”的error,或者如果你已经把所有声明都放在那个头文件里了,并且引用了它,那就无所谓。
注意:设立的时候数组或者指针越界了,但是没报错,不要有侥幸心理,这是因为结构体的内存中对齐存放的原因,以及初始化等等...
①结构体
struct content
{
char name[20];
char sex[5];
int age;
char address[20];
char phone[12];
};
struct contact_list
{
struct content list[MAX+1];
int sz;
};
② 枚举常量
enum INPUT
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT,
SECRET,
SHOW_SECRET,
REMOVE_SECRET
};
enum MODI
{
NAME=1,
SEX,
AGE,
ADDRESS,
PHONE
};
enum op
{
UP=1,
DOWN
};
③头文件,宏
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 100
#include
#include
#include
#include
④函数 (指针传参,可以改变值)(值传参只是一份临时拷贝)
void test();
void menu1();
void menu2();
void menu3();
void init(struct contact_list* pt);
void add_man(struct contact_list* pt);
void show_all(const struct contact_list* pt);
void del_man(struct contact_list* pt);
void search_man(const struct contact_list* pt);
void modify_man(struct contact_list* pt);
void sort_all(struct contact_list* pt);
void secret(struct contact_list* pt, struct contact_list* px);
void show_secret(const struct contact_list* pt,const struct contact_list* px);
void remove_secret(struct contact_list* pt, struct contact_list* px);
static int judge_local(struct contact_list* pt, char* Name);
void upsort(struct contact_list* pt);
void downsort(struct contact_list* pt);
int sort1(const void* e1, const void* e2);
int sort2(const void* e1, const void* e2);
int sort3(const void* e1, const void* e2);
int sort4(const void* e1, const void* e2);
int sort5(const void* e1, const void* e2);
int sort6(const void* e1, const void* e2);
int sort7(const void* e1, const void* e2);
int sort8(const void* e1, const void* e2);
int sort9(const void* e1, const void* e2);
int sort10(const void* e1, const void* e2);
//初始化
void init(struct contact_list* pt)
{
assert(pt);
pt->sz = 0;
memset(pt->list, 0, (MAX + 1) * sizeof(struct content));
}
菜单:
void menu1()
{
printf("***********************************************\n");
printf("********** 1,add ******* 2,del *******\n");
printf("******** 3,search ******* 4,modify *******\n");
printf("********** 5,show ******* 6,sort ********\n");
printf("********* 7,secret ******* 8,show_secret ****\n");
printf("** 9,remove_secret ******* 0,exit *********\n");
printf("***********************************************\n");
}
void add_man(struct contact_list* pt)
{
printf("请输入你要添加人的信息(重名者需要加上编号):>\n");
printf("姓名:>");
scanf("%s", pt->list[pt->sz].name);
printf("性别:>");
scanf("%s", pt->list[pt->sz].sex);
printf("地址:>");
scanf("%s", pt->list[pt->sz].address);
printf("手机号:>");
scanf("%s", pt->list[pt->sz].phone);
printf("年龄:>");
scanf("%d", &pt->list[pt->sz].age);
pt->sz++;
system("cls");
printf("添加成功\n");
}
主要要检验身份(三次机会)(自己设立)(此次我随便按的密码,什么密码都可以,大小不一样的话改一下代码就好)
void del_man(struct contact_list* pt)
{
printf("请输入密码以确保你的身份(七个字符):>");
int count = 3;
char str[8] = { 0 };
while (count--)
{
scanf("%s", str);
if (strcmp(str, "mmsszsd") == 0)
{
goto again;
}
printf("密码错误\n");
}
printf("你没有机会了\n");
return;
again:
show_all(pt);
printf("请输入一个你要删除的联系人的姓名:>");
char Name[20] = { 0 };
scanf("%s", Name);
int ret = judge_local(pt,Name);
if (ret == -1)
{
system("cls");
printf("查无此人\n");
return;
}
else
{
int i = 0;
for (i = ret; i < pt->sz; i++)
{
pt->list[i] = pt->list[i + 1];
}
pt->sz--;
system("cls");
printf("删除成功\n");
}
}
//判断位置函数
static int judge_local(struct contact_list* pt, char* Name)
{
int i = 0;
for (i = 0; i < pt->sz; i++)
{
if (strcmp(pt->list[i].name, Name) == 0)
return i;
}
return -1;
}
void search_man(const struct contact_list* pt)
{
printf("请输入一个你要查找的联系人的姓名:>");
char Name[20] = { 0 };
scanf("%s", Name);
int ret = judge_local(pt, Name);
if (ret == -1)
{
system("cls");
printf("查无此人\n");
return;
}
else
{
system("cls");
printf("查找成功\n");
int ij = 0;
for (ij = 0; ij < 60; ij++)
printf("-");
printf("\n");
printf("%-20s%-5s%-20s%-12s%-3s\n", "姓名", "性别", "地址", "手机号", "年龄");
printf("%-20s%-5s%-20s%-12s%-3d\n", pt->list[ret].name,
pt->list[ret].sex, pt->list[ret].address,
pt->list[ret].phone, pt->list[ret].age);
ij = 0;
for (ij = 0; ij < 60; ij++)
printf("-");
printf("\n");
}
}
还是要通过密码才能修改,然后通过menu2选择修改具体内容,输入0退出修改
void modify_man(struct contact_list* pt)
{
printf("请输入密码以确保你的身份(七个字符):>");
int count = 3;
char str[8] = { 0 };
while (count--)
{
scanf("%s", str);
if (strcmp(str, "mmsszsd") == 0)
{
goto again;
}
printf("密码错误\n");
}
printf("你没有机会了\n");
return;
again:
show_all(pt);
printf("请输入一个你要修改的联系人的姓名:>");
char Name[20] = { 0 };
scanf("%s", Name);
int ret = judge_local(pt, Name);
if (ret == -1)
{
system("cls");
printf("查无此人\n");
}
else
{
int input = 0;
do
{
menu2();
printf("请选择要修改什么:>");
scanf("%d", &input);
switch (input)
{
case NAME:
scanf("%s", pt->list[ret].name);
printf("修改成功\n");
break;
case SEX:
scanf("%s", pt->list[ret].sex);
printf("修改成功\n");
break;
case AGE:
scanf("%d", &pt->list[ret].age);
printf("修改成功\n");
break;
case ADDRESS:
scanf("%s", pt->list[ret].address);
printf("修改成功\n");
break;
case PHONE:
scanf("%s", pt->list[ret].phone);
printf("修改成功\n");
break;
case EXIT:
printf("退出成功\n");
break;
default:
printf("输入失败\n");
break;
}
} while (input);
}
}
void menu2()
{
printf("***********************************************\n");
printf("***** 1,NAME ****** 2,SEX ***************\n");
printf("****** 3,AGE ****** 4,ADDRESS **********\n");
printf("**** 5,PHONE ****** 0,EXIT ***************\n");
printf("***********************************************\n");
}
void show_all(const struct contact_list* pt)
{
int ij = 0;
for (ij = 0; ij < 60; ij++)
printf("-");
printf("\n");
printf("%-20s%-5s%-20s%-12s%-3s\n", "姓名", "性别", "地址", "手机号", "年龄");
int i = 0;
if (pt->sz == 0)
{
printf("空\n");
}
else
{
for (i = 0; i < pt->sz; i++)
{
if (pt->list[i].name[0] != '#')
{
printf("%-20s%-5s%-20s%-12s%-3d\n", pt->list[i].name,
pt->list[i].sex, pt->list[i].address,
pt->list[i].phone, pt->list[i].age);
}
else
{
int j = 0;
for (j = 0; j < 60; j++)
printf("#");
printf("\n");
}
}
}
ij = 0;
for (ij = 0; ij < 60; ij++)
printf("-");
printf("\n");
}
首先是规律(升序还是降序)
其次是标准(根据人的某一信息排序)
分别要用到菜单
void sort_all(struct contact_list* pt)
{
int option = 0;
do
{
menu3();
printf("请输入要以什么规律排序:>");
scanf("%d", &option);
switch (option)
{
case UP:
upsort(pt);
break;
case DOWN:
downsort(pt);
break;
case EXIT:
printf("退出成功\n");
break;
default:
printf("输入失败\n");
break;
}
} while (optionDOWN);
}
如果觉得switch太麻烦了,可以用函数指针数组
void upsort(struct contact_list* pt)
{
int input = 0;
do
{
menu2();
printf("请输入要以什么为标准排序:>");
scanf("%d", &input);
switch (input)
{
case NAME:
qsort(pt->list, pt->sz, sizeof(struct content), sort1);
printf("排序成功\n");
break;
case SEX:
qsort(pt->list, pt->sz, sizeof(struct content), sort2);
printf("排序成功\n");
break;
case AGE:
qsort(pt->list, pt->sz, sizeof(struct content), sort3);
printf("排序成功\n");
break;
case ADDRESS:
qsort(pt->list, pt->sz, sizeof(struct content), sort4);
printf("排序成功\n");
break;
case PHONE:
qsort(pt->list, pt->sz, sizeof(struct content), sort5);
printf("排序成功\n");
break;
case EXIT:
printf("退出成功\n");
break;
default:
printf("输入失败\n");
break;
}
} while (inputPHONE);
}
void downsort(struct contact_list* pt)
{
int input = 0;
do
{
menu2();
printf("请输入要以什么为标准排序:>");
scanf("%d", &input);
switch (input)
{
case NAME:
qsort(pt->list, pt->sz, sizeof(struct content), sort6);
printf("排序成功\n");
break;
case SEX:
qsort(pt->list, pt->sz, sizeof(struct content), sort7);
printf("排序成功\n");
break;
case AGE:
qsort(pt->list, pt->sz, sizeof(struct content), sort8);
printf("排序成功\n");
break;
case ADDRESS:
qsort(pt->list, pt->sz, sizeof(struct content), sort9);
printf("排序成功\n");
break;
case PHONE:
qsort(pt->list, pt->sz, sizeof(struct content), sort10);
printf("排序成功\n");
break;
case EXIT:
printf("退出成功\n");
break;
default:
printf("输入失败\n");
break;
}
} while (inputPHONE);
}
这边要定义排序标准函数(怎么样这个结构体才算大)
根据升降序,还有五个成员,可以划分出10个标准
int sort1(const void* e1, const void* e2)
{
return strcmp(((struct content*)e1)->name, ((struct content*)e2)->name);
}
int sort2(const void* e1, const void* e2)
{
return strcmp(((struct content*)e1)->sex, ((struct content*)e2)->sex);
}
int sort3(const void* e1, const void* e2)
{
return ((struct content*)e1)->age - ((struct content*)e2)->age;
}
int sort4(const void* e1, const void* e2)
{
return strcmp(((struct content*)e1)->address, ((struct content*)e2)->address);
}
int sort5(const void* e1, const void* e2)
{
return strcmp(((struct content*)e1)->phone, ((struct content*)e2)->phone);
}
int sort6(const void* e1, const void* e2)
{
return strcmp(((struct content*)e2)->name, ((struct content*)e1)->name);
}
int sort7(const void* e1, const void* e2)
{
return strcmp(((struct content*)e2)->sex, ((struct content*)e1)->sex);
}
int sort8(const void* e1, const void* e2)
{
return ((struct content*)e2)->age - ((struct content*)e1)->age;
}
int sort9(const void* e1, const void* e2)
{
return strcmp(((struct content*)e2)->address, ((struct content*)e1)->address);
}
int sort10(const void* e1, const void* e2)
{
return strcmp(((struct content*)e2)->phone, ((struct content*)e1)->phone);
}
同样的,也是需要进行密码识别,这里体现了另一个结构体变量的作用,来记忆,被码了的内容
void secret(struct contact_list* pt, struct contact_list* px)
{
assert(px);
printf("请输入密码以确保你的身份(七个字符):>");
int count = 3;
char str[8] = { 0 };
while (count--)
{
scanf("%s", str);
if (strcmp(str, "mmsszsd") == 0)
{
goto again;
}
printf("密码错误\n");
}
printf("你没有机会了\n");
return;
again:
show_all(pt);
printf("请输入你要码掉的人的姓名:>");
char Name[20] = { 0 };
scanf("%s", Name);
int ret = judge_local(pt, Name);
if (ret == -1)
{
system("cls");
printf("查无此人\n");
return;
}
else
{
memcpy(px->list + ret, pt->list + ret, sizeof(struct content));
memset(pt->list + ret, '#', sizeof(struct content));
}
printf("保密成功\n");
}
同样要输入密码,成功后临时展示全部完整信息
void show_secret(const struct contact_list* pt, const struct contact_list* px)
{
printf("请输入密码以确保你的身份(七个字符):>");
int count = 3;
int ij = 0;
char str[8] = { 0 };
while (count--)
{
scanf("%s", str);
if (strcmp(str, "mmsszsd") == 0)
{
goto again;
}
printf("密码错误\n");
}
printf("你没有机会了\n");
return;
again:
for (ij = 0; ij < 60; ij++)
printf("-");
printf("\n");
printf("%-20s%-5s%-20s%-12s%-3s\n", "姓名", "性别", "地址", "手机号", "年龄");
int i = 0;
if (pt->sz == 0)
{
printf("空\n");
}
else
{
for (i = 0; i < pt->sz; i++)
{
if(pt->list[i].name[0]!='#')
{
printf("%-20s%-5s%-20s%-12s%-3d\n", pt->list[i].name,
pt->list[i].sex, pt->list[i].address,
pt->list[i].phone, pt->list[i].age);
}
else
{
printf("%-20s%-5s%-20s%-12s%-3d\n", px->list[i].name,
px->list[i].sex, px->list[i].address,
px->list[i].phone, px->list[i].age);
}
}
ij = 0;
for (ij = 0; ij < 60; ij++)
printf("-");
printf("\n");
printf("展示成功\n");
}
}
取消对某一行的信息遮蔽
void remove_secret(struct contact_list* pt, struct contact_list* px)
{
printf("请输入密码以确保你的身份(七个字符):>");
int count = 3;
char str[8] = { 0 };
while (count--)
{
scanf("%s", str);
if (strcmp(str, "mmsszsd") == 0)
{
goto again;
}
else
printf("密码错误\n");
}
printf("你没有机会了\n");
return;
again:
show_all(pt);
printf("你要揭晓的序号(从1开始由上往下数):>");
int n = 0;
scanf("%d", &n);
if (pt->list[n - 1].name[0] == '#')
memmove(&pt->list[n - 1], &px->list[n - 1], sizeof(struct content));
show_all(pt);
printf("揭晓成功\n");
}
主函数调用
#include "通讯录相关声明.h"
int main()
{
test();
return 0;
}
游离态 (carefree-state) - Gitee.com