兜兜转转的终于解决了卡了我这么久的问题,
第一步考虑的就错了然后一歪再歪越来越复杂😌思维还是要发散开来每一个环节都考虑上
写的通讯录,很拙,等后面知识丰富点再加之改进。
int main()
{
game();
return 0;
}
main函数,不太喜欢再main里面写一大堆,然后就用game函数调用了。
//这里都是.h文件,声明都在这里进行
//一些注意的点我会加之标记
void game();
void menu();//打印菜单函数
void chushihua(struct uct* p1);
//见名知意,初始化函数把结构体内容置空
void addformation(struct uct* p1);
//添加成员信息
void showformation(struct uct* p1);
//显示成员信息
void subformation(struct uct* p1);
//删除成员信息
void searchformation(const struct uct* p1);
//查找成员信息
void modifyformation(struct uct* p1);
//对成员排序
int cmp_stu_name(const void* p1, const void* p2);
//自己实现的结构体比较方法
//枚举类型,第一个为0,配合后面的switch case 语句使用。
enum arr
{
EXIT,
ADD,
SUB,
SEARCH,
MODIFY,
SHOW,
SORT
};
//这是结构体成员信息
struct information
{
char name[MAX_NAME];
int age;
char set[MAX_SAT];
char tele[MAX_TELE];
char addr[MAX_ADDR];
};
//上一个结构体变量定义在这个结构体里面了,
//同时还要给一个数组,为了后面方便接受信息就这样定义了两个结构体
struct uct
{
struct information data[MAX];
int size;
};
//打印菜单函数
void menu()
{
printf("*******************************\n");
printf("*****1 add 2 sub*****\n");
printf("*****3 search 4 modify*****\n");
printf("*****5 show 6 sort****\n");
printf("********* 0 exit *********\n");
printf("*******************************\n");
}
//初始化
void chushihua(struct uct* p1)
{
memset(p1->data, 0, sizeof(p1->data));
//这里的data是数组首元素,在sizeof()里面代表的是整个数组
p1->size = 0;
}
//添加成员信息
//使用结构体指针更方便也节省空间
void addformation(struct uct* p1)
{
if (p1->size == MAX)//判断是否超出范围
{
printf(" 存储已满 !\n");
}
else
{
printf("请添加信息\n");
printf("请输入名字 -> \n");
scanf("%s", p1 ->data[p1->size].name);
printf("请输入年龄 -> \n");
scanf("%d",&(p1 ->data[p1->size].age));
printf("请输入性别 -> \n");
scanf("%s", p1 ->data[p1->size].set);
printf("请输入电话 -> \n");
scanf("%s", p1 ->data[p1->size].tele);
printf("请输入地址 -> \n");
scanf("%s", p1 ->data[p1->size].addr);
printf(" 添加成功 !\n");
p1->size++;
//添加几个成员信息size就是几
}
}
//显示成员信息
//这个是从第0个开始往后打印
//打印到size个就停止
void showformation(struct uct* p1)
{
int i = 0;
if (p1->size == 0)
{
printf("内容为空\n");
}
else
{
printf("%-16s\t%-3s\t%-6s\t%-12s\t%-15s\n","姓名","年龄","性别","电话","地址");
for (i = 0; i < p1->size; ++i)
{
printf("%-16s\t%-3d\t%-5s\t%-12s\t%-15s\n", p1->data[i].name,
p1->data[i].age,
p1->data[i].set,
p1->data[i].tele,
p1->data[i].addr);
}
}
}
//因为这个查找 改 和 删 都要用到
//所以就使用static修饰,同时独立实现查找功能
//减少代码冗余
static int sertch(const struct uct* p1,char name[MAX_NAME])
{
int i = 0;
for (i = 0; i < p1->size; ++i)
{
if (0 == strcmp(p1->data[i].name, name))
return i;
}
return -1;
}
//删除联系人
void subformation(struct uct* p1)
{
char name[MAX_NAME];
printf("请输入要删除人的名字");
scanf("%s", name);
int ret = sertch(p1,name);
if (ret == -1)
//上面的如果没有找到就会返回-1,跟这个配合上
printf("该联系人不存在!\n\n");
else
{
//用的还是土方法,删除哪一个就从下一个信息一个个往前挪
while (ret < p1->size - 1)
{
p1->data[ret] = p1->data[ret + 1];
++ret;
}
p1->size--;
printf("删除成功!\n\n");
}
}
//查找函数
//因为只负责查找可以使用const修饰,防止被改变
void searchformation(const struct uct* p1)
{
char name[MAX_NAME];
printf("请输入你要查找人的姓名:");
scanf("%s", name);
int i = sertch(p1, name);
if (i == -1)
printf("未查找到该联系人\n");
else
{
printf("%-16s\t %-3s\t %-6s\t %-12s\t %-15s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-16s\t%-3d\t%-5s\t%-12s\t%-15s\n", p1->data[i].name,
p1->data[i].age,
p1->data[i].set,
p1->data[i].tele,
p1->data[i].addr);
}
}
//修改信息函数
void modifyformation(struct uct* p1)
{
char name[MAX_NAME];
printf("请输入要修改人的信息:");
scanf("%s", name);
int ret = sertch(p1, name);
if (ret == -1)
{
printf("未找到该联系人\n");
}
else
{
printf("请添加信息\n");
printf("请输入名字 -> \n");
scanf("%s", p1->data[ret].name);
printf("请输入年龄 -> \n");
scanf("%d", &(p1->data[ret].age));
printf("请输入性别 -> \n");
scanf("%s", p1->data[ret].set);
printf("请输入电话 -> \n");
scanf("%s", p1->data[ret].tele);
printf("请输入地址 -> \n");
scanf("%s", p1->data[ret].addr);
printf(" 修改 成功 !\n");
}
}
//这个是结构体里面的字符串比较函数
//这个函数不熟的话会有点坑
//它会被qsort函数调用很多次,所以你一句一句代码运行的时候
//它会运行很多次,因为要判断很多次,所以会给你一种卡在return走不动的假象
//有点坑,新手还是要多研究研究这个函数
//尽量要发散思维想的更全面一些
int cmp_stu_name(const void* p1,const void* p2)
{
//return strcmp(((struct information*)p1)->name, ((struct information*)p2)->name);
return strcmp(((struct information*)p1)->name,((struct information*)p2)->name);
}
//这就是main函数里面调用的实现功能函数了
//各种函数都在这里调用
void game()
{
int input = 0;
struct uct s1;
chushihua(&s1);
do
{
menu();
printf("\n");
printf("\n");
printf("please input a number:");
scanf_s("%d", &input);
//输入input p配合后面的switch语句
int sz = s1.size;
//每次求这个数组元素个数的时候
//本能反应直接sizeof(数组名)/sizeof(数组首元素[0]),唉咋说呢,还是要细心
//qsort排序可以直接输入你要排序的数组元素个数
//其实不需要传整个数组所有的元素
//然后因为这个还要再想办法怎么只打印有信息的
//很简单的一个地方但是有时候就是没有反应过来
//代码出bug的时候一步步调试,找不到问题就放一放,睡一觉起来说不定就有思路了呢
switch (input)
{
//里面配合枚举使用
//exit是0 add是1,等等
case ADD:
addformation(&s1);
break;
case SUB:
subformation(&s1);
break;
case SEARCH:
searchformation(&s1);
break;
case MODIFY:
modifyformation(&s1);
break;
case SHOW:
showformation(&s1);
break;
case SORT:
//库函数,快速排序
qsort(s1.data, sz, sizeof(s1.data[0]),cmp_stu_name);
break;
case EXIT:
printf("退出 \n");
break;
default :
printf("输入错误!\n");
break;
}
} while (input);//输入零循环判断为假退出循环
}
结束
开心的一天来自解决问题,感觉整个人都轻松了,今天晚上心血来潮写了一遍扫雷,还差最后一个功能,那个递归一下一大片的还得好好想想
明天做好分享出来吧,有些坑的地方会做标记
还是要细心。
得马上十点半了,得赶快睡觉,年轻人身体重要😌