C语言实验-动态顺序表实现简易通讯录(一)+ https://developer.aliyun.com/article/1519323?spm=a2c6h.13148508.setting.14.25634f0etWq3TD
6.按姓名查找联系人
toFindName是我们要查找的联系人姓名,由用户输入。将用户输入的待查找姓名与通讯录中的所有联系人姓名挨个比较,若查找到了,就返回该联系人在通讯录中的下标,若没有找到,返回-1。
代码如下:
//3-查找 按姓名 int searchContact(Contact *con,const char *toFindName) { assert(con); for (int i = 0; i < con->size; i++) { if (strcmp(con->arr[i].name, toFindName) == 0) { return i; } } return -1; }
7.删除联系人
删除联系人的函数中,先对通讯录进行了判空,以保证在执行运行操作时候通讯录非空。
调用了查找函数,来判断要删除的联系人在表中是否存在。若存在,则执行删除操作:与顺序表的删除一样,将该联系人后面的所有联系人(从第i+1到第n)依次向前移动1位,将要删除的联系人信息覆盖删除。
在删除完毕后必须将个数size减1.
代码如下:
//2-按姓名删除 void delContact(Contact* con,const char *toDelName) { assert(con); if (con->size == 0) { printf("通讯录为空!删除失败!\n"); return; } if (searchContact(con, toDelName) != -1) { for (int i = searchContact(con, toDelName); i < con->size-1; i++) { con->arr[i] = con->arr[i + 1]; } con->size--; printf("删除成功!\n"); } else { printf("该联系人不存在,删除失败!\n"); } }
8.修改指定联系人的指定信息
通过姓名检索指定的要更改其信息的联系人,仍然调用查找函数实现检索。
在找到目标联系人的信息后,我们通过相应的选择来决定要更改该联系人的哪一信息(姓名/性别/电话/住址)。注意,此处联系人信息均应输入字符串,对字符串的赋值不能直接用等号,而应用strcpy()。
代码如下:
//4-修改 按姓名 void modifyContact(Contact* con) { assert(con); if (con->size == 0) { printf("通讯录为空!修改失败!\n"); return; } char toModifyName[20] = { 0 }; printf("请输入要更改的联系人的姓名:"); scanf(" %s", toModifyName); int modifyI = searchContact(con, toModifyName); if (modifyI != -1) { printf("请输入您要修改的信息项:\n"); printf("0.姓名:\n"); printf("1.性别:\n"); printf("2.电话:\n"); printf("3.住址:\n"); int input = 0; scanf(" %d", &input); printf("请输入修改后的信息:"); char tmp[50] = { 0 }; scanf(" %s", tmp); switch (input) { case 0: strcpy(con->arr[modifyI].name, tmp); break; case 1: strcpy(con->arr[modifyI].sex, tmp); break; case 2: strcpy(con->arr[modifyI].tel, tmp); break; case 3: strcpy(con->arr[modifyI].addr, tmp); break; } printf("修改成功!\n"); } else { printf("修改失败!联系人不存在!\n"); } }
9.查看所有联系人
注意打印格式,%-20s 的含义为打印一个字符串,该字符串左对齐(-号)并占20个比特位(若不足20个比特位则右侧补空格)。
代码如下:
//5-展示 void showContact(Contact *con) { printf("%-20s", "姓名"); printf("%-20s", "性别"); printf("%-20s", "电话"); printf("%-20s", "住址"); printf("\n"); for(int i = 0; i < con->size; i++) { printf("%-20s", con->arr[i].name); printf("%-20s", con->arr[i].sex); printf("%-20s", con->arr[i].tel); printf("%-20s", con->arr[i].addr); printf("\n"); } }
打印后的对齐效果如下:
10.按指定关键字对联系人进行排序
实现思路与修改指定联系人的指定信息类似。在排序时我们可以采用c库函数qsort()
注意qsort实现结构体排序时,比较函数cmp的书写。需先将e1和e2强制类型转换为结构体指针(People*),再通过结构体指针访问联系人信息关键字。
//比较函数 static int cmp_name(const void* e1, const void* e2) { //本质是字符串比较->使用strcmp函数 return strcmp(((People*)e1)->name, ((People*)e2)->name); } static int cmp_sex(const void* e1, const void* e2) { return strcmp(((People*)e1)->sex, ((People*)e2)->sex); } static int cmp_tel(const void* e1, const void* e2) { return strcmp(((People*)e1)->tel, ((People*)e2)->tel); } static int cmp_addr(const void* e1, const void* e2) { return strcmp(((People*)e1)->addr, ((People*)e2)->addr); } //6-排序 void sortContact(Contact *con) { assert(con); printf("要按哪一项排序?\n"); printf("0.姓名:\n"); printf("1.性别:\n"); printf("2.电话:\n"); printf("3.住址:\n"); int input = 0; scanf(" %d", &input); switch (input) { case 0: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_name); break; case 1: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_sex); break; case 2: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_tel); break; case 3: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_addr); break; } printf("排序成功!\n"); }
三、完整代码
Contact.cpp
1.
#define _CRT_SECURE_NO_WARNINGS 1 #include"Contact.h" //初始化 void Init(Contact* con) { con->arr = NULL; con->size = con->capacity = 0; } //判断增容 static void CheckCapacity(Contact* con) { assert(con); if (con->capacity == con->size) { int newCapacity = con->capacity == 0 ? 4 : 2 * con->capacity; People* tmp = (People*)realloc(con->arr, sizeof(People) * newCapacity); if (tmp == NULL) { perror("CheckCapacity"); exit(-1); } else { con->arr = tmp; con->capacity = newCapacity; } } } //1-添加 void addContact(Contact *con) { //判断增容 CheckCapacity(con); //添加内容 printf("姓名:"); scanf(" %s", con->arr[con->size].name); printf("性别:"); scanf(" %s", con->arr[con->size].sex); printf("电话:"); scanf(" %s", con->arr[con->size].tel); printf("住址:"); scanf(" %s", con->arr[con->size].addr); con->size++; printf("添加联系人成功!\n"); } //2-按姓名删除 void delContact(Contact* con,const char *toDelName) { assert(con); if (con->size == 0) { printf("通讯录为空!删除失败!\n"); return; } if (searchContact(con, toDelName) != -1) { for (int i = searchContact(con, toDelName); i < con->size-1; i++) { con->arr[i] = con->arr[i + 1]; } con->size--; printf("删除成功!\n"); } else { printf("该联系人不存在,删除失败!\n"); } } //3-查找 按姓名 int searchContact(Contact *con,const char *toFindName) { assert(con); for (int i = 0; i < con->size; i++) { if (strcmp(con->arr[i].name, toFindName) == 0) { return i; } } return -1; } //4-修改 按姓名 void modifyContact(Contact* con) { assert(con); if (con->size == 0) { printf("通讯录为空!修改失败!\n"); return; } char toModifyName[20] = { 0 }; printf("请输入要更改的联系人的姓名:"); scanf(" %s", toModifyName); int modifyI = searchContact(con, toModifyName); if (modifyI != -1) { printf("请输入您要修改的信息项:\n"); printf("0.姓名:\n"); printf("1.性别:\n"); printf("2.电话:\n"); printf("3.住址:\n"); int input = 0; scanf(" %d", &input); printf("请输入修改后的信息:"); char tmp[50] = { 0 }; scanf(" %s", tmp); switch (input) { case 0: strcpy(con->arr[modifyI].name, tmp); break; case 1: strcpy(con->arr[modifyI].sex, tmp); break; case 2: strcpy(con->arr[modifyI].tel, tmp); break; case 3: strcpy(con->arr[modifyI].addr, tmp); break; } printf("修改成功!\n"); } else { printf("修改失败!联系人不存在!\n"); } } //5-展示 void showContact(Contact *con) { printf("%-20s", "姓名"); printf("%-20s", "性别"); printf("%-20s", "电话"); printf("%-20s", "住址"); printf("\n"); for(int i = 0; i < con->size; i++) { printf("%-20s", con->arr[i].name); printf("%-20s", con->arr[i].sex); printf("%-20s", con->arr[i].tel); printf("%-20s", con->arr[i].addr); printf("\n"); } } static int cmp_name(const void* e1, const void* e2) { //本质是字符串比较->使用strcmp函数 return strcmp(((People*)e1)->name, ((People*)e2)->name); } static int cmp_sex(const void* e1, const void* e2) { return strcmp(((People*)e1)->sex, ((People*)e2)->sex); } static int cmp_tel(const void* e1, const void* e2) { return strcmp(((People*)e1)->tel, ((People*)e2)->tel); } static int cmp_addr(const void* e1, const void* e2) { return strcmp(((People*)e1)->addr, ((People*)e2)->addr); } //6-排序 void sortContact(Contact *con) { assert(con); printf("要按哪一项排序?\n"); printf("0.姓名:\n"); printf("1.性别:\n"); printf("2.电话:\n"); printf("3.住址:\n"); int input = 0; scanf(" %d", &input); switch (input) { case 0: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_name); break; case 1: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_sex); break; case 2: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_tel); break; case 3: qsort(con->arr, con->size, sizeof(con->arr[0]), cmp_addr); break; } printf("排序成功!\n"); } //7-销毁 void destroyContact(Contact *con) { assert(con); free(con->arr); con->arr = NULL; con->size = con->capacity = 0; printf("销毁成功!\n"); }
Contact.h
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> enum Choice { texit, add, del, search, modify, show, sort }; typedef struct People { char name[20]; //姓名 char sex[6]; //性别 char tel[15]; //电话 char addr[50]; //住址 }People; typedef struct Contact { People* arr; int size; int capacity; }Contact; //初始化 void Init(Contact* con); //1-添加 void addContact(Contact* con); //5-展示 void showContact(Contact* con); //2-按姓名删除 void delContact(Contact* con, const char* toDelName); //3-查找 按姓名 int searchContact(Contact* con, const char* toFindName); //4-修改 按姓名 void modifyContact(Contact* con); //6-排序 void sortContact(Contact* con); //7-销毁 void destroyContact(Contact* con);
Test.cpp
#define _CRT_SECURE_NO_WARNINGS 1 #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 *****\n"); printf("**************************************\n"); printf("\n"); } int main() { Contact contact; Init(&contact); int input = 0; printf("通讯录初始化成功!\n"); do { menu(); printf("请输入选项:>"); scanf(" %d", &input); switch (input) { case add: { addContact(&contact); break; } case del: { printf("请输入要删除的联系人姓名:>"); char name[20] = { 0 }; scanf(" %s", name); delContact(&contact, name); break; } case search: { printf("请输入要查找的联系人姓名:>"); char name[20] = { 0 }; scanf(" %s", name); searchContact(&contact, name); break; } case modify: modifyContact(&contact); break; case show: showContact(&contact); break; case sort: sortContact(&contact); break; case texit: printf("退出程序!通讯录销毁!\n"); destroyContact(&contact); //注意要销毁 break; default: printf("请输入正确的选项!\n"); break; } fflush(stdin); printf("\n"); } while (input); return 0; }