时间:2022-01-12 08:51:56 | 栏目:C代码 | 点击:次
1.为了更好地展示,制作一个菜单,在菜单中有 添加,删除,查找,修改,排序,清空,退出的选项。
2.因为起先要进入程序一趟,所以用do????while循环(输入选项来看具体操作,退出还是其他操作)
#include "contact.h" void menu() { printf("*****************************************\n"); printf("******** Contact ******\n"); printf("******** 1.add 2. del ******\n"); printf("******** 3.search 4.modify ******\n"); printf("******** 5.print 6.empty ******\n"); printf("******** 7.sort 0.exit ******\n"); printf("*****************************************\n"); } enum Option //为什么要使用枚举 //因为这样可以防止命名污染,而且使用枚举,枚举成员有默认初始值,默认从0开始,这样省去的诸多的代码量 { EXIT, ADD, DEL, SEARCH, MODIFY, PRINT, EMPTY, SORT, }; int main() { //先打印菜单,展示通讯录功能 int input = 0; //先进行设置一个通讯录 //设置每个人的信息 //初始化通讯录 //通讯录中的一个元素 contact con; //contact 是自定义数据类型,包括一个联系人的基本信息 InitContact(&con); do { menu();//设置菜单 printf("请选择>"); scanf("%d", &input); switch (input) { case ADD: //实现添加功能 AddContact(&con); break; case DEL: //实现删除功能 DelContact(&con); break; case SEARCH: //实现查找功能 SearchContact(&con); break; case MODIFY: //实现修改功能 ModifyContact(&con); break; case PRINT: //显示 PrintContact(&con); break; case SORT: //实现名字排序 SortContact(&con); break; case EMPTY: //实现清空 EmptyContact(&con); break; case EXIT: //退出程序 ExitContact(&con); break; default: printf("输入错误,请重新输入\n"); } } while (input); return 0; }
1.声明各类功能函数
2.定义各个常量,把常量定义成通俗易懂的变量,便于在多处使用。
3.定义结构体,自定义类型中,有一个联系人的基本信息。
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_NAME 20 //定义姓名字符串的大小为20 #define MAX_SEX 10 //定义性别字符串的大小为10 #define MAX_TELE 12 //定义电话字符串的大小为12 #define MAX_ADDR 20 //定义地址字符串的大小为20 #define MAX 1000 //定义通讯录的最大容量为1000 #define IN_NUM 3 //在动态申请空间时默认空间为3 #define SET_NUM 2 //当基本信息大于3份时,开辟两个空间 //设置每一个人的信息 //通讯录规定要求一共有1000个人 typedef struct base { char name[MAX_NAME]; //姓名 char sex[MAX_SEX]; //性别 int age; //年龄 char tele[MAX_TELE]; //电话 char addr[MAX_ADDR]; //住址 }base; //设置1000人的通讯录 //静态版 //typedef struct contact //{ // // int sz; //计算当前通讯录中联系人的个数 // base data[MAX]; //存放联系人的信息 // //}contact; //动态初始化通讯录 typedef struct contact { //有个结构体类型中需要,监视通讯录人数的一项,还有当联系人为3人时,这时候要进行增容 int sz; //计算当前联系人的个数 base* data; //指向动态申请的空间,存放联系人的信息 int capciaty; //计算当前通讯录中的最大容量 }contact; //初始化通讯录 void InitContact(contact* pc); //添加联系人 void AddContact(contact* pc); //显示 void PrintContact(contact* pc); //删除联系人 void DelContact(contact* pc); //查找联系人 void SearchContact(contact* pc); //修改信息 void ModifyContact(contact* pc); //排序联系人信息 void SortContact(contact* pc); //清空联系人信息 void EmptyContact(contact* pc); //退出程序时,释放空间 void ExitContact(contact* pc);
contact.c 1.初始化通讯录
动态申请空间
默认在动态空间中存放3个基本单位信息
void InitContact(contact* pc) { pc->data = (base*)malloc(sizeof(base) * IN_NUM); if (pc->data == NULL) //如果空间开辟失败 //退出程序 { perror("InitContact"); return; } //把每个成员都设置为0 pc->sz = 0; pc->capciaty = IN_NUM; }
2.添加联系人
当默认的空间被装满时,然后以后的每一次都开辟两个基本空间
void AddContact(contact* pc) { //先判断通讯录中是否满了 //if (pc->sz == MAX) //{ // printf("通讯录已满,无法添加\n"); // return; //} //动态判断人的个数是否满足3 if (pc->sz == pc->capciaty) { printf("开始增容:\n"); //从新设置一个指针,存放新开辟的内存 base* ptr = (base*)realloc(pc->data, (pc->capciaty + SET_NUM) * sizeof(base)); //判断是否开辟成功 if (ptr == NULL) { printf("开辟失败\n"); perror("AddContact"); return; } else { printf("开辟成功\n"); //开辟成功的话,把ptr转交给data来维护,这样在内存释放的时候只需要释放pc->data pc->data = ptr; //增加基本信息数量 pc->capciaty += SET_NUM; } 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].tele); printf("住址>"); scanf("%s", pc->data[pc->sz].addr); pc->sz++; printf("添加成功\n"); }
3.显示联系人信息
逐一打印联系人信息,注意之间的距离(保持美观)
//显示 void PrintContact(contact* pc) { //显示标题 printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址"); int i = 0; for (i = 0; i < pc->sz; i++) { printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr); } }
4.删除联系人
在删除联系人之前,首先要查找要删除联系人的名字,然后进行删除,注意如何删除
让删除的这个单位的后一个单位去覆盖这个删除的单位(这样原来要删除的地方变成了后面一个值) i = i+1
当通讯录中有被删除着的名字时,返回这个单位的下标
当通讯录中没有时,返回-1
//查找联系人 static int Find_name(contact* pc, char name[]) { int i = 0; for ( i = 0; i < pc->sz; i++) { if (strcmp(pc->data[i].name, name) == 0) { return i; } } return -1; } //删除联系人 void DelContact(contact* pc) { //如果通讯录是空的 if (pc->sz == 0) { printf("通讯为空,无需删除\n"); return; } //下进行查找被删除联系人的名字 char name[MAX_NAME]; printf("请输入要删除联系人的名字:"); scanf("%s", name); int ret = Find_name(pc, name); if (ret == -1) { printf("该联系人不存在\n"); return; } //删除 //删除项后边的一项,覆盖前面的一项 for (int i = ret; i < pc->sz; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); }
4.查找联系人
在删除联系人的时候有查找函数,在这里直接引用,并打印。这个人的信息。
//查找联系人 void SearchContact(contact* pc) { char name[MAX_NAME]; printf("请输入要查找联系人的名字:"); scanf("%s", name); int ret = Find_name(pc, name); if (ret == -1) { printf("该联系人不存在\n"); return; } printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址"); printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr); }
5.修该联系人信息
还是现在通讯录中查找这个联系人,在进行输入修改
//修改信息 void ModifyContact(contact* pc) { char name[MAX_NAME]; printf("请输入要修改联系人的名字:"); scanf("%s", name); int ret = Find_name(pc, name); if (ret == -1) { printf("该联系人不存在\n"); return; } printf("姓名是>"); scanf("%s", pc->data[ret].name); printf("年龄是>"); scanf("%d", &pc->data[ret].age); printf("性别>"); scanf("%s", pc->data[ret].sex); printf("电话>"); scanf("%s", pc->data[ret].tele); printf("住址>"); scanf("%s", pc->data[ret].addr); }
6.排序联系人姓名
利用冒泡排序对联系人的名字进行排序(也可以使用快排)
//排序 //交换名字,但是名字要和联系人的信息匹配 //先比较名字,根据名字的大小,再排序 static void SwapByname(base* pa, base* pb) { base b; b = *pa; *pa = *pb; *pb = b; } void SortContact(contact* pc) { printf("开始排序\n"); //使用冒泡排序对联系人的名字进行排序 int i = 0; int j = 0; for (i = 0; i < pc->sz; i++) { for (j = 0; j < pc-> sz - i - 1; j++) { if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0) { //实现交换姓名 SwapByname(&pc->data[j], &pc->data[j + 1]); } } } printf("排序结束\n"); }
7.清空联系人
在这里直接使用sz?C,就可以删除
//清空 void EmptyContact(contact* pc) { //如果原来的通讯录是空的就无须清空 if (pc->sz == 0) { printf("通讯录为空,无需清空\n"); return; } printf("开始清除数据:\n"); int num = pc->sz; for (int i = 0; i < num; i++) { pc->sz--; } printf("清空完毕\n"); }
8.退出通讯录
手动开辟,手动释放
//退出程序,释放空间 void ExitContact(contact* pc) { //释放空间 free(pc->data); pc->data = NULL; pc->sz = 0; pc->capciaty = 0; }
运行展示: