5.改变指定人员的信息
代码如下:
int searchContact(Contact* pc) { assert(pc); char name[20]; int pos = -1; scanf("%s", name); //查询 for (int i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { pos = i; } } return pos; } //协助查找函数被,找到被查改人员在data数组的下标位置,再进行修改 void changeContact(Contact* pc) { assert(pc); //先找到 int pos = searchContact(pc); printf("请输入名字:>"); scanf("%s", pc->data[pos].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pos].age)); printf("请输入性别:>"); scanf("%s", pc->data[pos].sex); printf("请输入地址:>"); scanf("%s", pc->data[pos].addr); printf("请输入电话:>"); scanf("%s", pc->data[pos].tele); printf("更改完成, 请继续操作\n"); }
协助于查找函数,找到被查改人员在data数组的下标位置,再进行修改。
6.打印通讯录人员信息
代码如下:
void showContact(Contact* pc) { assert(pc); if (pc->sz == 0) { return; }//可以有可无 printf("%-20s\t%-5s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话"); for (int i = 0; i < pc->sz; i++) { printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele); } printf("打印完成\n"); }
对于printf中的 %-20s \ t 进行解释,-表示左对齐,20表示这个字符串20个位置,保持左对齐打印,\t 是字表符,是为了更加美观,使得各项数据对齐
7.排序通讯录
排序的依据有很多,我们这里是按照姓名大小排序,使用函数strcmp,实际上也可以使用qsort函数进行排序
代码如下:
void sortContact(Contact* pc) { assert(pc); if (pc->sz == 0) { printf("通讯录中暂无元素\n"); return; } Contact s = { 0 }; for (int i = 0; i < pc->sz-1; i++) { for (int j = i; j < pc->sz-1; j++) { if (strcmp(pc->data[j].name, pc->data[j + 1].name)==1) { s.data[j] = pc->data[j]; pc->data[j] = pc->data[j + 1]; pc->data[j + 1] = s.data[j]; } } } }
使用的是strcmp函数结合冒泡排序,这样还可以使用qsort函数,使用方法可以参考
【C语言进阶】指针的进阶(下)_小王学代码的博客-CSDN博客
qsort函数代码如下:
int compare(const void* e1, const void* e2) { return *((int*)e1) - *((int*)e2); } void sort(Contact*pc) { qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare); }
三、动态通讯录
动态通讯录相较于静态通讯录主要在结构体、初始化、增加成员的时候进行了改动
1.改动结构体
代码如下:
//构建通讯录所需的结构体 typedef struct PeopleInfo { char name[NAME_MAX];//姓名 int age;//年龄 char sex[NAME_MAX];//性别 char addr[ADDR_MAX];//地址 char tele[TELE_MAX];//电话号码 }PeopleInfo; //实现动态通讯录 typedef struct Contact { PeopleInfo *data;//表示存储的通讯录最大人员数 int sz;//表示当前Contact通讯录人员个数 int capacity; //表示当前容量 作为扩容的依据 }Contact;
讲data数组变成指针的形式,不再固定通讯录容量大小,可以适当扩容
2.改动初始化
使用malloc函数进行内存申请,初始化
代码如下:
//这是动态通讯录的初始化 void InitContact(Contact* pc) { //进行初始化的时候,我们当然可以直接 assert(pc);//断言 pc->sz = 0; PeopleInfo *ptr=(PeopleInfo*)calloc(MAX1,sizeof(PeopleInfo)); if (ptr == NULL) { perror("malloc::data"); return; } pc->data = ptr; pc->capacity=MAX1; }
对data空间进行申请,MAX1 表示的是初始的时候data容量大小
3.改动添加人员函数
实现扩容机制,如果sz和capacity相等,表示人员个数和容量相等,不能再添加人员了,这个时候需要check_capacity函数进行检查是否满,并扩容
代码如下:
//动态通讯录 void check_capacity(Contact* pc) { PeopleInfo* ptr = (PeopleInfo*)realloc(pc->data, sizeof(PeopleInfo)*(pc->capacity+MAX2)); if (ptr == NULL) { perror("check_capacity"); return; } pc->data = ptr; pc->capacity = pc->capacity + MAX2; } void addContact(Contact* pc) { assert(pc); if (pc->sz == pc->capacity) { //使用realloc函数 进行扩容 check_capacity(pc); printf("扩容完成\n"); } printf("请输入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:>"); scanf("%s", pc->data[pc->sz].sex); printf("请输入地址:>"); scanf("%s", pc->data[pc->sz].addr); printf("请输入电话:>"); scanf("%s", pc->data[pc->sz].tele); printf("添加完成,请继续操作\n"); pc->sz++; }
使用了realloc函数进行扩容处理
四、整体通讯录代码
1.静态通讯录
都有三种文件,test.c Contact.c Contact.h,分别是框架,实现,头文件声明,三个作用
1.test.c文件
#define _CRT_SECURE_NO_WARNINGS #include"Contact.h" //这边进行主要的通讯录流程操作 void menu() { printf("***********************************************\n"); printf("****** 1.add 2.del ******\n"); printf("****** 3.search 4.change ******\n"); printf("****** 5.show 6.sort ******\n"); printf("****** 0.exit ******\n"); printf("***********************************************\n"); } void test() { //打印选择菜单 int input = 0; int pos = 0; Contact pc; //Contact pc={0}; //当然可以这样初始化,但是不一定后来初始化都这样,所以有InitContact() InitContact(&pc); do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: addContact(&pc); break; case 2: delContact(&pc); break; case 3: pos = searchContact(&pc); if (pos == -1) { printf("没有查找到该成员\n"); } else { printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc.data[pos].name, pc.data[pos].age, pc.data[pos].sex, pc.data[pos].addr, pc.data[pos].tele); } break; case 4: changeContact(&pc); break; case 5: showContact(&pc); break; case 6: sort(&pc); break; case 0: printf("退出通讯录\n"); break; default: break; } } while (input); } int main() { test(); return 0; }
2.Contact.c
#define _CRT_SECURE_NO_WARNINGS #include"Contact.h" //用来实现头文件的代码 // 这是静态初始化 void InitContact(Contact* pc) { //进行初始化的时候,我们当然可以直接 pc->sz = 0; memset(pc->data, 0, sizeof(pc->data)); //memset 函数 这样的话,从data这个数组的地址开始 sizeof(pc->data)个字节,都赋值为0 } 静态通讯录 void addContact(Contact* pc) { assert(pc); if (pc->sz == MAX) { printf("通讯录已满,无法添加\n"); return; } printf("请输入名字:>"); scanf("%s", pc->data[pc->sz].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pc->sz].age)); printf("请输入性别:>"); scanf("%s", pc->data[pc->sz].sex); printf("请输入地址:>"); scanf("%s", pc->data[pc->sz].addr); printf("请输入电话:>"); scanf("%s", pc->data[pc->sz].tele); printf("添加完成,请继续操作\n"); pc->sz++; } void delContact(Contact* pc) { assert(pc); printf("请选择删除的目标:>"); if (pc->sz == 0) { return; } //删除的话只需要找到对应的要删除的数据,比如以名字为准,先找到,然后再讲其后面的元素覆盖前面的 int pos = searchContact(pc); //换位置 if (pos == -1) { printf("没有查找到该成员\n"); return; } for (int i = pos; i < pc->sz - 1; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--;//直接--不用管换位置之后最后一个数字的问题 printf("删除完成\n"); } int searchContact(Contact* pc) { assert(pc); char name[20]; int pos = -1; scanf("%s", name); //查询 for (int i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { pos = i; } } return pos; } void showContact(Contact* pc) { assert(pc); if (pc->sz == 0) { return; }//可以有可无 printf("%-20s\t%-5s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话"); for (int i = 0; i < pc->sz; i++) { printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele); } printf("打印完成\n"); } void changeContact(Contact* pc) { assert(pc); //先找到 int pos = searchContact(pc); printf("请输入名字:>"); scanf("%s", pc->data[pos].name); printf("请输入年龄:>"); scanf("%d", &(pc->data[pos].age)); printf("请输入性别:>"); scanf("%s", pc->data[pos].sex); printf("请输入地址:>"); scanf("%s", pc->data[pos].addr); printf("请输入电话:>"); scanf("%s", pc->data[pos].tele); printf("更改完成, 请继续操作\n"); } void sortContact(Contact* pc) { assert(pc); if (pc->sz == 0) { printf("通讯录中暂无元素\n"); return; } Contact s; InitContact(&s); for (int i = 0; i < pc->sz-1; i++) { for (int j = 0; j < pc->sz-1-i; j++) { if (strcmp(pc->data[j].name, pc->data[j + 1].name)==1) { s.data[j] = pc->data[j]; pc->data[j] = pc->data[j + 1]; pc->data[j + 1] = s.data[j]; } } } } int compare(const void* e1, const void* e2) { return *((int*)e1) - *((int*)e2); } void sort(Contact*pc) { qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare); }