头文件,命名函数结构体和一些宏
#pragma once #define max_name 20//个个数据的最大值 #define max_sex 5 #define max_tel 12 #define max_add 30 #define madd 3//每次扩展容量的大小 #include <string> #include <stdio.h> #include <assert.h> #include <stdlib.h> enum operate//使用enum,在主函数能明显的知道个个含义 { Exit, Add, Del, Search, Modify, Show, Sort, Clear }; typedef struct person//定义人的个个信息 { char name[max_name]; int age; char sex[max_sex]; char tel[max_tel]; char add[max_add]; }person; typedef struct contact//组合成contact { person* date;//存放数据空间 int sz;//有效个数 int cy;//容量 }contact; //赋值contact void Inticontact( contact* pc); //增加联系人 void Addcontact(contact* pc); //展示所有联系人 void Showcontact(const contact* pc); //删除联系人 void Delcontact(contact* pc); //查找联系人 void Searchcontact(const contact* pc); //修改联系人 void Modifycontact(contact *pc); //按名字排序 void Sortcontact(contact* pc); //清除数据 void Clearcontact(contact* pc); //退出 void Exitcontact(contact* pc);
第二个文件,实现个个函数
int Checkcontact(contact* pc)//检查开辟的内存是否足够进行内存的伸缩 { assert(pc);//断言 if (pc->sz == pc->cy) { person* p =(person*) realloc(pc->date, (madd + pc->cy) * sizeof(person)); if (p == NULL)//判断是否开辟成功 { perror("Checkcontact");//打印错误 return 0; } printf("增容成功\n"); pc->date = p;//把开辟空间的内存首地址赋给date pc->cy += madd;//重新对容量值赋值 } return 1; }
void Loadcontact(contact* pc) {//读取文件函数,将上一次存到文件里面的信息进行读取 FILE* p=fopen("contact.date", "rb"); //以二进制读取(后面二进制存储的) if (p == NULL)//判断文件是否打开 { perror("Loadcontact");//打印错误 return; } person per = { 0 };//创建一个person的变量存储读取的值 while (fread(&per, sizeof(person), 1, p))//读取完的时候返回0 { Checkcontact(pc);//检查容量是否足够,然后进行内存的伸缩 pc->date[pc->sz] = per; pc->sz++; } fclose(p);//关闭文件 p = NULL;//赋空,防止成为野指针 }
void Inticontact( contact*pc)//初始化 { assert(pc);//断言 pc->date = (person*)malloc(madd * sizeof(person)); //开辟初始空间 if (pc->date == NULL)//判断开辟是否成功 { perror("Inticontact");//打印错误 return; } pc->sz = 0; pc->cy = add; Loadcontact(pc);//读取上次文件的信息 }
void Addcontact(contact* pc)//增加联系人 { assert(pc);//断言 Checkcontact(pc);//检查内存是否足够 printf("请输入姓名->"); scanf("%s", pc->date[pc->sz].name); printf("请输入年龄->"); scanf("%d",&( pc->date[pc->sz].age)); printf("请输入性别->"); scanf("%s", pc->date[pc->sz].sex); printf("请输入电话->"); scanf("%s", pc->date[pc->sz].tel); printf("请输入地址->"); scanf("%s", pc->date[pc->sz].add); printf("联系人添加完成\n"); pc->sz++;//内存里面的指向 }
void Showcontact(const contact* pc)//展示函数 { assert(pc); printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名","年龄","性别","电话","地址");//打印最上面的目录 for (int i = 0; i< pc->sz; i++) { printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->date[i].name, pc->date[i].age, pc->date[i].sex, pc->date[i].tel, pc->date[i].add); }//打印每个数据 }
int findcontact(const contact* pc, char name[]) {//查找函数,后面的多个函数要使用,就直接写成函数 for (int i = 0; i < pc->sz; i++) { if (strcmp(name, pc->date[i].name)) return i; } return -1; }
void Delcontact(contact* pc) { if (!pc->sz)//判断是否有存取人 { printf("联系人位空,不能删除\n"); return; } char name[max_name] = { 0 }; printf("输入要删除人的名字->"); scanf("%s", name); int del = findcontact(pc, name); //判断是否找到 if (del == -1) { printf("要删除的人不存在\n"); return ; } for (int i = del; i < pc->sz-1; i++) {//找到,从后往前移,删掉这个值 pc->date[i] = pc->date[i + 1]; } pc->sz--; printf("删除成功\n"); }
void Searchcontact(const contact* pc)//查询 { char name[max_name] = { 0 }; printf("输入要查找人的名字->"); scanf("%s", name); int del = findcontact(pc, name);//同理 if (del == -1) { printf("不存在该人\n"); return; } printf("该人信息:\n"); printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址"); printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->date[del].name, pc->date[del].age, pc->date[del].sex, pc->date[del].tel, pc->date[del].add); }
void menu2() { printf("**************************\n"); printf("****1 年龄 2 性别 ****\n"); printf("****3 电话 4 地址 ****\n"); printf("****0 退出 ****\n"); } void Modifycontact(contact* pc)//修改联系人 { printf("请输入被修改人姓名:"); char temp[max_name] = { 0 }; scanf("%s", temp); int del = findcontact(pc, temp); if (del == -1) { printf("不存在该人\n"); return; } printf("请输入要修改的信息:"); int input; do { menu2(); scanf("%d", &input); switch (input) { case 0:break; case 1:printf("请输入要修改年龄:"); scanf("%d", pc->date[del].age); break; case 2:printf("请输入要修改性别:"); scanf("%s", pc->date[del].sex); break; case 3:printf("请输入要修改电话:"); scanf("%s", pc->date[del].tel); break; case 4:printf("请输入要修改地址:"); scanf("%s", pc->date[del].add); break; defalut:break; } } while (input); printf("修改完成\n");
void Sortcontact(contact* pc) {//冒泡排序,也可以用sort进行快排也更方便 for (int i = 0; i < pc->sz; i++) { for (int j = 0; j < pc->sz - 1 - i; j++) { if (strcmp(pc->date[j].name, pc->date[j + 1].name)>0) { char temp[max_name] = { 0 }; strcpy(temp, pc->date[j].name); strcpy(pc->date[j].name, pc->date[j+1].name); strcpy( pc->date[j+1].name,temp); } } } }
void Clearcontact(contact* pc) { assert(pc); free(pc->date);//释放date,重新开辟 pc->date = (person*)malloc(madd * sizeof(person)); if (pc->date == NULL) { perror("Inticontact"); return; } pc->sz = 0; pc->cy = madd; }
void Exitcontact(contact* pc)//退出 { FILE* p = fopen("contact.date", "wb"); //打开or创造一个文件读写存储 if (p == NULL)//是否成功 { perror("Exitcontact"); return; } for (int i = 0; i < pc->sz; i++) {//一个一个的进行读写 fwrite(pc->date + i, sizeof(person), 1, p); } fclose(p);//关闭文件 p = NULL;//置空 free(pc->date);//释放内存 pc->date = NULL;//赋空 }
//主函数 #include "contact.h" void menu()//打印菜单 { printf("***************************\n"); printf("***1.add 2.del *****\n"); printf("***3.search 4.modify*****\n"); printf("***5.show 6.sort *****\n"); printf("***0.exit 7.clear *****\n"); printf("***************************\n"); } void test() { int input; contact con; Inticontact(&con); do//使用do while { menu(); scanf("%d", &input); switch (input)//使用枚举,增加代码可读性 { case Exit: Exitcontact(&con); break; case Add:Addcontact(&con); break; case Del: Delcontact(&con); break; case Search: Searchcontact(&con); break; case Modify: Modifycontact(&con); break; case Show: Showcontact(&con); break; case Sort: Sortcontact(&con); break; case Clear: Clearcontact(&con); break; default: break; } } while (input); } int main() { test(); return 0; }