目录
①通讯录模板
②先使用未定义函数(理想函数功能)填补模板
③定义实现函数
一,大概的形式
首先,需要两个结构体来支撑,第一个结构体(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<stdio.h> #include<string.h> #include<assert.h> #include<stdlib.h>
④函数 (指针传参,可以改变值)(值传参只是一份临时拷贝)
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 (option<EXIT || option>DOWN); }
如果觉得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 (input<EXIT || input>PHONE); } 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 (input<EXIT || input>PHONE); }
这边要定义排序标准函数(怎么样这个结构体才算大)
根据升降序,还有五个成员,可以划分出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; } 大家
可以自己去试一下效果哦!下面是我的gitee网址,里面(12月代码)可以找到哦(可以有改进)(*^_^*)