2.8 排序通讯录
介绍一下用于各种类型数据排序的库函数qsort
void qsort(void*base,//待排序的数据的起始位置 size_t num,//待排序的数据的元素个数 size_t width,//待排序的数据的元素大小(单位字节) int(*cmp)(const void*e1,const void*e2)//函数指针-比较函数 )
关于库函数的具体使用可以去看我的另一篇博客指针的进阶
link
int cmp_name(const void* e1, const void* e2) { //因为数据类型是peoinfo所以这里需要进行强制类型转换 return strcmp(((peoinfo*)e1)->name, ((peoinfo*)e2)->name); } void sortcontact(contact* p) { assert(p); qsort(p->data, p->count, sizeof(peoinfo),cmp_name); printf("排序完成\n"); }
因为需要排序通讯录,所以可以根据联系人的姓名,年龄,地址进行排序,在这里所选择的是按照姓名进行排序。
至于其余的排序方式,读者可以试着自己编写代码去实现。
3.改进a-动态版本
动态版本
3.1菜单选择增加
void menu() { printf("**********************************************\n"); printf("**** 1.add 2.rearch ******\n"); printf("**** 3.del 4.modify ******\n"); printf("**** 5.show 6.sort ******\n"); printf("**** 7.destory 0.exit ******\n"); printf("**********************************************\n"); }
3.2修改初始联系人数目
#define Max 3//联系人数量
3.3初始化功能修改为动态开辟内存
void Initcontact(contact* p) { assert(p); p->count = 0; p->data = (peoinfo*)calloc(Max , sizeof(peoinfo)); if (p->data == NULL) { printf("%s\n", strerror(errno)); //若开辟内存失败,打印错误原因 return; } p->capacity = Max; return 0; }
3.4 判断联系人数量是否已满,或进行扩容
//判断通讯录中联系人数量是否已满 if (p->count == p->capacity) { printf("数量已满,需要增容\n"); peoinfo* str = (peoinfo*)realloc(p->data, (p->capacity+Max) * sizeof(peoinfo)); if (str == NULL)//扩容失败 { printf("%s\n", strerror(errno)); return; } else//扩容成功 { p->data = str; p->capacity += Max; } }
3.5增加销毁通讯录的功能
void destorycontact(contact* p) { assert(p); free(p->data); p->data = NULL; printf("通讯录已销毁\n"); }
4.改进b-文件版本
4.1 在销毁通讯录之前将通讯录保存到文件中
void savecontact(const contact* p) { assert(p); //采用二进制形式将通讯录写入文件中 FILE* pfwrite = fopen("text.txt", "wb"); if (pfwrite == NULL) { printf("%s\n", strerror(errno)); return; } //写文件 int i = 0; for (i = 0; i < p->count; i++) { //一次写入一个联系人的信息 fwrite(p->data + i, sizeof(peoinfo), 1, pfwrite); } //关闭文件 fclose(pfwrite); pfwrite = NULL; }
4.2在初始化通讯录过程中,将文件信息加载到通讯录
void loadcontact(contact* p) { assert(p); FILE* pfread = fopen("test.txt", "rb"); if (pfread == NULL) { printf("%s\n", strerror(errno)); return; } peoinfo peo = { 0 }; //每次读一位联系人到通讯录中 while (fread(&peo, sizeof(peoinfo), 1, pfread) == 1) { //检查通讯录是否需要扩容 checkcontact(p); p->data[p->count] = peo; p->count++; } //关闭文件 fclose(pfread); pfread = NULL; }