哪里有html企业网站模板下载,北京传媒公司排行榜,网站建设团队定制,免费建立手机网站本节应用是要用顺序表实现一个通讯录#xff0c;收录联系人的姓名、性别、电话号码、住址、年龄 顺序表的实现在上一节中已经完成了#xff0c;本节的任务其实就是应用上节写出来的代码的那些接口函数功能#xff0c;做出来一个好看的#xff0c;可… 本节应用是要用顺序表实现一个通讯录收录联系人的姓名、性别、电话号码、住址、年龄 顺序表的实现在上一节中已经完成了本节的任务其实就是应用上节写出来的代码的那些接口函数功能做出来一个好看的可视化的东西 首先把准备工作做好创立好通讯录的头文件Contest.h和源文件Contest.c还有测试源文件,再把上一节的顺序表文件链接过来在这节中直接使用上节的函数功能 1. 通讯录数据类型 首先我们在Contect.h文件中把通讯录结构体写出来再改一个好写的名字 这边数组长度是用宏定义的为了方便以后更改 2. 通讯录操作方法 现在我们写一下通讯录的操作发方法跟之前的写法一样写一个菜单函数然后用do···while和switch语句让用户选择要进行什么操作 在Contect.c文件中写menu()函数并包含上它的头文件Contect.h 用户操作方案写在test.c中 3. 顺序表改成通讯录 现在我们要将上节的顺序表稍加修改将arr中的元素从int型改成通讯录结构体型的此时需要在SeqList.h中包含上Contect.h 修改一下SLDatatype的表示对象为Info就完成了 4. 通讯录里提供的操作 这个时候我们需要用到SeqList文件中的内容了但是我们不能在Contest.h中引用SeqList.h了这样会导致头文件嵌套问题你包含我我包含你没完没了程序就出错了所以我们的头文件包含要定好一个顺序就像这样 确定好这个顺序了那我们如何使用SeqList.h文件中的内容呢此时的解决方法就是前置声明因为内容在后面但是我们要在前面使用它所以我们可以在前面声明一下这个内容就可以在前面使用它了 前置声明之后再改个名字从顺序表改成通讯录方便后边辨识和使用 这时我们运行一下会发现喜提一大堆错误这时不要慌问题就出现在之前顺序表的查找和打印函数上了它们的类型错误导致的报错我们只需要把它们注释掉就可以了 4.1 通讯录的初始化和销毁 这块功能非常简单我们只需要复用SeqList.h中的函数就可以 然后在测试文件中调试一下 发现没问题该创建的东西都创建好了 4.2 增删查改查看通讯录
4.2.1 增 首先创建一个临时变量info暂时存放一个人的所有信息然后复用函数就可以了 在把增的功能添加到主函数之前我们要在do···while外边写好创建、初始化和销毁通讯录顺序表的功能 然后把ContectAdd()函数放到增的位置就好了 4.2.2 查看通讯录 先写查看通讯录用来方便检验之后的代码 然后把这个功能加到main函数里头 4.2.3 查 查找的话可以通过那5个方面去查这里我就写一个通过名字查的 这个FindByName()函数因为后面还要用所以就单拎出来写的注意用到了字符串操作函数要引用一下头文件。 4.2.4 删 4.2.5 改 5. 完整代码
Contect.h完整代码
//通讯录数据类型
#define NAME_MAX 100
#define GENDER_MAX 10
#define TEL_MAX 12
#define ADDR_MAX 100
typedef struct PersonInfo
{char name[NAME_MAX];char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];int age;
}Info;//通讯录菜单
void menu();//使用顺序表的前置声明
struct SeqList;
typedef struct SeqList Contect;//通讯录里提供的操作
//通讯录的初始化和销毁
void ContectInit(Contect* pcon);
void ContectDestory(Contect* pcon);//增、删、改、查、查看通讯录
//增
void ContectAdd(Contect* pcon);//查看通讯录
void ContectShow(Contect* pcon);//查
void ContectFind(Contect* pcon);//删
void ContectDel(Contect* pcon);//改
void ContectModify(Contect* pcon); Contect.c完整代码
#includeSeqList.h//通讯录菜单
void menu()
{printf(******************通讯录*******************\n);printf(*********1.添加联系人 2.删除联系人*********\n);printf(*********3.修改联系人 4.查找联系人*********\n);printf(*********5.查看通讯录 0.退出通讯录*********\n);printf(*******************************************\n);
}//通讯录里提供的操作
//通讯录的初始化和销毁
void ContectInit(Contect* pcon)
{SLInit(pcon);
}
void ContectDestory(Contect* pcon)
{SLDestory(pcon);
}//增、删、改、查、查看通讯录
//增
void ContectAdd(Contect* pcon)
{//创建一个通讯录结构体用来临时存放一个人的所有信息Info info;printf(请输入联系人姓名:);scanf(%s, info.name);printf(请输入联系人性别:);scanf(%s, info.gender);printf(请输入联系人电话:);scanf(%s, info.tel);printf(请输入联系人地址:);scanf(%s, info.addr);printf(请输入联系人年龄:);scanf(%d, info.age);//保存到通讯录顺序表中SLPushBack(pcon, info);
}//查看通讯录
void ContectShow(Contect* pcon)
{ for (int i 0; i pcon-size; i){printf(-------------------------------\n);printf(姓名%s\n, pcon-arr[i].name);printf(性别%s\n, pcon-arr[i].gender);printf(电话%s\n, pcon-arr[i].tel);printf(地址%s\n, pcon-arr[i].addr);printf(年龄%d\n, pcon-arr[i].age);}
}//查
#includestring.h
int FindByName(Contect* pcon, char name[])
{for (int i 0; i pcon-size; i){if (strcmp(pcon-arr[i].name, name) 0){//找到了return i;}}//没找到return -1;
}void ContectFind(Contect* pcon)
{char name[NAME_MAX];printf(请输入要查找的人名:);scanf(%s, name);int ret FindByName(pcon, name);if (ret 0){printf(要查找的联系人不存在!\n);return;}//找到了打印一下查找的联系人的信息printf(-------------------------------\n);printf(姓名%s\n, pcon-arr[ret].name);printf(性别%s\n, pcon-arr[ret].gender);printf(电话%s\n, pcon-arr[ret].tel);printf(地址%s\n, pcon-arr[ret].addr);printf(年龄%d\n, pcon-arr[ret].age);
}//删
void ContectDel(Contect* pcon)
{//删除前先查找找到了可以删找不到不能删printf(请输入要删除的联系人姓名:);char name[NAME_MAX];scanf(%s, name);int ret FindByName(pcon, name);if (ret 0){printf(要删除的联系人不存在!\n);return;}//执行删除操作SLErase(pcon, ret);printf(删除成功\n);
}//改
void ContectModify(Contect* pcon)
{//修改前先查找找到了改找不到不能改printf(请输入要修改的联系人姓名:);char name[NAME_MAX];scanf(%s, name);int ret FindByName(pcon, name);if (ret 0){printf(要修改的联系人不存在!\n);return;}//执行修改操作printf(开始修改\n);printf(请输入姓名:);scanf(%s, pcon-arr[ret].name);printf(请输入性别:);scanf(%s, pcon-arr[ret].gender);printf(请输入电话:);scanf(%s, pcon-arr[ret].tel);printf(请输入地址:);scanf(%s, pcon-arr[ret].addr);printf(请输入年龄:);scanf(%d, pcon-arr[ret].age);printf(联系人修改成功\n);
} SeqList.h完整代码
#includestdio.h
#includestdlib.h
#includeassert.h
#includeContect.htypedef Info SLDatatype;typedef struct SeqList
{SLDatatype* arr; //存储数据的底层结构int capacity; //记录顺序表的空间大小int size; //有效数据个数
}SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestory(SL* ps);
//void SLPrint(SL* ps);//顺序表插入数据
//从尾部插入
void SLPushBack(SL* ps, SLDatatype x);
//从头部插入
void SLPushFront(SL* ps, SLDatatype x);//顺序表删除数据
//从尾部删除
void SLPopBack(SL* ps);
//从头部删除
void SLPopFront(SL* ps);//顺序表任意位置增删数据
//指定位置前面增加数据
void SLInsert(SL* ps, int pos, SLDatatype x);
//删除指定位置数据
void SLErase(SL* ps, int pos);//在顺序表中查找x
//int SLFind(SL* ps, SLDatatype x);//在顺序表中把pos位置的数据改成x
void SLChange(SL* ps, int pos, SLDatatype x); SeqList.c完整代码
#includeSeqList.h//初始化和销毁
void SLInit(SL* ps)
{ps-arr NULL;ps-capacity ps-size 0;
}void SLDestory(SL* ps)
{assert(ps);if (ps-arr)//arr不是空的再释放也可以不判断{free(ps-arr);//free空指针函数什么都不会做} ps-arr NULL;ps-capacity ps-size 0;
}//void SLPrint(SL* ps)
//{
// assert(ps);
// for (int i 0; i ps-size; i)
// {
// printf(%d , ps-arr[i]);
// }
// printf(\n);
//}//顺序表插入数据
//判断空间是否足够不够就扩容
void SLCheckCapacity(SL* ps)
{if (ps-size ps-capacity)//空间不够时{int newCapacity ps-capacity 0 ? 4 : 2 * ps-capacity;//为了防止扩容失败导致数据丢失扩容后的空间地址先不给ps-arrSLDatatype* tmp (SLDatatype*)realloc(ps-arr, newCapacity * sizeof(SLDatatype));if (tmp NULL)//扩容失败{printf(realloc fail!\n);exit(1);//错误退出码1}//扩容成功ps-arr tmp;ps-capacity newCapacity;}
}//从尾部插入
//逻辑空间足够就直接尾插空间不够就扩容扩容一般是扩容当前空间的2倍
void SLPushBack(SL* ps, SLDatatype x)
{assert(ps);//判断空间够不够不够就扩容SLCheckCapacity(ps);//走到这里时空间肯定够了直接在后面插入数据ps-arr[ps-size] x;//ps-size;
}//从头部插入
//逻辑将所有数据向后挪一位再在第一位插入数据
void SLPushFront(SL* ps, SLDatatype x)
{assert(ps);//判断空间够不够不够就扩容SLCheckCapacity(ps);//此时空间够了将所有数据往后挪一位再放数据for (int i ps-size; i 0; i--){ps-arr[i] ps-arr[i - 1];}ps-arr[0] x;ps-size;
}
//在添加完元素之后一定要记得 ps-size 增加一个//顺序表删除数据
//从尾部删除
//逻辑顺序表为空不能执行删除顺序表不为空直接删最后一个数据
void SLPopBack(SL* ps)
{assert(ps);assert(ps-size);//数据为空报警//顺序表不为空ps-size--;//看不见最后一位等于删了最后一位
}
//从头部删除
//逻辑顺序表为空不删顺序表不为空将数据们往前挪一位
void SLPopFront(SL* ps)
{assert(ps);assert(ps-size);//顺序表不为空for (int i 0; i ps-size-1; i){ps-arr[i] ps-arr[i 1];}ps-size--;
}
//在删除完数据之后也要记得减size//顺序表任意位置增删数据
//指定位置前面增加数据
void SLInsert(SL* ps, int pos, SLDatatype x)
{assert(ps);assert(pos 0 pos ps-size);SLCheckCapacity(ps);//pos及之后的数据往后挪一位for (int i ps-size; i pos; i--){ps-arr[i] ps-arr[i - 1];}ps-arr[pos] x;ps-size;
}//删除指定位置数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos 0 pos ps-size);//pos以后的数据向前挪一位for (int i pos; i ps-size - 1; i){ps-arr[i] ps-arr[i 1];}ps-size--;
}//在顺序表中查找x
//int SLFind(SL* ps, SLDatatype x)
//{
// assert(ps);
// for (int i 0; i ps-size; i)
// {
// if (ps-arr[i] x)
// {
// return i;//找到了返回下标
// }
// }
// return -1;//没找到返回-1
//}//在顺序表中把pos位置的数据改成x
void SLChange(SL* ps, int pos, SLDatatype x)
{assert(ps);assert(pos 0 pos ps-size);ps-arr[pos] x;
} 最后这套代码是用完一次之后里面存的联系人信息就没了这时我们可以借助文件操作函数将数据保存下来这样下次打开的时候还能加载出来
C语言·文件操作-CSDN博客文章浏览阅读923次点赞24次收藏21次。本节介绍了文件的用处如何用文件指针打开和关闭文件流的读写函数fgetc fputc fgets fputs fscanf fprintf fread fwrite和字符串的的格式化输入输出函数sscanf sprintf控制文件指针实现随机读写的函数fseek ftell rewind文件结束相关函数feof ferror文件缓冲区的概念https://blog.csdn.net/atlanteep/article/details/134894644?spm1001.2014.3001.5501