目录
一、基于动态顺序表实现通讯录
二、代码实现
2.1 通讯录的初始化
2.2 通讯录的销毁
2.3 通讯录的展示
2.4 通讯录添加联系人信息
2.5 通讯录删除联系人信息
2.6 通讯录修改联系人信息
2.7 通讯录的查找联系人信息
2.8 将通讯录中联系人信息保存到文件中
2.9 从文件中读取数据到通讯录中
三、将上述代码做成一个小游戏
正文开始
一、基于动态顺序表实现通讯录
C语言基础要求:结构体、动态内存管理、顺序表、文件操作
1.1、功能要求
- 至少能够存储100个人的通讯信息
- 能够保存用户户信息:名字、性别、年龄、电话、地址等
- 通讯录的初始化
- 通讯录的销毁
- 通讯录增加联系人信息
- 删除指定联系人
- 查找制定联系人
- 修改指定联系人
- 显示联系人信息
二、代码实现
2.1 通讯录的初始化
Contact.h——主要用来声明实现通讯录结构,以及声明通讯录的方法
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
//定义联系人的数据结构
//姓名, 性别,年龄 , 电话 , 地址
typedef struct personInfo
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}peoInfo;
//首先得先给通讯录起个名字
typedef struct SeqList Contact;
//1.通讯录的初始化
void ContactInit(Contact* con);
Contact.c——实现通讯录的方法
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
#include "SeqList.h"
//1.通讯录的初始化
void ContactInit(Contact* con)
{
//实际上就是对顺序表进行初始化
SLInit(con);//这里的方法是上一篇中的方法
}
2.2 通讯录的销毁
Contact.h
//2.通讯录的销毁
void ContactDestroy(Contact* con);
Contact.c
//2.通讯录的销毁
void ContactDestroy(Contact* con)
{
SLDestroy(con); //同上
}
2.3 通讯录的展示
Contact.h
//3.展示通讯录数据
void ShowContact(Contact* con);
Contact.c
//3. 展示通讯录数据
void ShowContact(Contact* con)
{
//表头:姓名 性别 年龄 电话 地址
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
//遍历通讯录,按照格式打印每个联系人的数据
for (int i = 0; i < con->size; i++)
{
printf("%3s %4s %4d %4s %4s\n",
con->arr[i].name,
con->arr[i].gender,
con->arr[i].age,
con->arr[i].tel,
con->arr[i].addr
);
}
}
2.4 通讯录添加联系人信息
Contact.h
//4.通讯录添加数据
void ContactAdd(Contact* con);
Contact.c
//4.通讯录添加数据
void ContactAdd(Contact* con)
{
//首先我们得获取用户输入的内容:姓名+性别+年龄+电话+地址
peoInfo Info;
printf("请输入你想要添加联系人的姓名:");
scanf("%s", Info.name);
printf("请输入你想要添加联系人的性别:");
scanf("%s", Info.gender);
printf("请输入你想要添加联系人的年龄:");
scanf("%d", &Info.age);
printf("请输入你想要添加联系人的电话:");
scanf("%s", Info.tel);
printf("请输入你想要添加联系人的地址:");
scanf("%s", Info.addr);
//获取到数据之后,就需要往通讯录中写入
SLPushBack(con, Info);
}
test.c ——测试文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
#include "Contact.h"
Contact_test01()
{
Contact con;
//1.通讯录得初始化
ContactInit(&con);
//4.尾插联系人信息
ContactAdd(&con);
//3.展示所以联系人信息
ShowContact(&con);
//2.通讯录的销毁
ContactDestroy(&con);
}
int main()
{
Contact_test01();
return 0;
}
2.5 通讯录删除联系人信息
Contact.h
//5.通讯录删除数据
void ContactDel(Contact* con);
Contact.c
//5.通讯录删除数据
void ContactDel(Contact* con)
{
//想要删除,就需要将他给找出来
printf("请输入你想要删除联系人得姓名:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindbyName(con, name);
if (ret < 0)
{
printf("要删除得联系人数据不存在!\n");
return;
}
SLErase(con, ret);
printf("删除成功!\n");
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
#include "Contact.h"
Contact_test01()
{
Contact con;
//1.通讯录得初始化
ContactInit(&con);
//4.尾插联系人信息
ContactAdd(&con);
//3.展示所以联系人信息
ShowContact(&con);
//5.删除联系人信息
ContactDel(&con);
ShowContact(&con);
//2.通讯录的销毁
ContactDestroy(&con);
}
int main()
{
Contact_test01();
return 0;
}
2.6 通讯录修改联系人信息
Contact.h
//6.通讯录修改数据
void ContactModify(Contact* con);
Contact.c
//6.通讯录修改数据
void ContactModify(Contact* con)
{
printf("请输入你想要修改联系人的姓名:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindbyName(con, name);
if (ret < 0)
{
printf("抱歉,通讯录中没有这个联系人!\n");
return;
}
printf("请输入你想修改后联系人的姓名:");
scanf("%s", con->arr[ret].name);
printf("请输入你想修改后联系人的性别:");
scanf("%s", con->arr[ret].gender);
printf("请输入你想修改后联系人的年龄:");
scanf("%d", &con->arr[ret].age);
printf("请输入你想修改后联系人的电话:");
scanf("%s", con->arr[ret].tel);
printf("请输入你想修改后联系人的地址:");
scanf("%s", con->arr[ret].addr);
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
#include "Contact.h"
Contact_test01()
{
Contact con;
//1.通讯录得初始化
ContactInit(&con);
//4.尾插联系人信息
ContactAdd(&con);
//3.展示所以联系人信息
ShowContact(&con);
//5.删除联系人信息
ContactDel(&con);
ShowContact(&con);
//6.修改联系人的信息
ContactModify(&con);
ShowContact(&con);
//2.通讯录的销毁
ContactDestroy(&con);
}
int main()
{
Contact_test01();
return 0;
}
2.7 通讯录的查找联系人信息
Contact.h
//7.通讯录的查找
void ContactFind(Contact * con);
Contact.c
//7.查找联系人的信息
void ContactFind(Contact* con)
{
printf("请输入你想要查找联系人的姓名:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindbyName(con, name);
if (ret < 0)
{
printf("没有这个联系人的信息!");
return;
}
//开始打印
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%3s %4s %4d %4s %4s\n",
con->arr[ret].name,
con->arr[ret].gender,
con->arr[ret].age,
con->arr[ret].tel,
con->arr[ret].addr
);
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
#include "Contact.h"
Contact_test01()
{
Contact con;
//1.通讯录得初始化
ContactInit(&con);
//4.尾插联系人信息
ContactAdd(&con);
//3.展示所以联系人信息
ShowContact(&con);
//5.删除联系人信息
ContactDel(&con);
ShowContact(&con);
//6.修改联系人的信息
ContactModify(&con);
ShowContact(&con);
//7.查找联系人的信息
ContactFind(&con);
//2.通讯录的销毁
ContactDestroy(&con);
}
int main()
{
Contact_test01();
return 0;
}
2.8 将通讯录中联系人信息保存到文件中
Contact.h
//8.将通讯录中的数据保存到文件中
SaveContact(&con);
Contact.c
//8.将通讯录的数据写入到文件中
void SaveContact(Contact* con)
{
FILE* pf = fopen("contact.txt", "wb");
assert(pf);
for (int i = 0; i < con->size; i++)
{
fwrite(con->arr + i, sizeof(peoInfo), 1, pf);
}
printf("通讯录数据保存成功!\n");
fclose(pf);
pf = NULL;
}
2.9 从文件中读取数据到通讯录中
Contact.h
void LoadContact(Contact* con);
Contact.c
//9.从文件中读取数据到通讯录中
void LoadContact(Contact* con)
{
FILE* pf = fopen("contact.txt", "rb");
if (pf == NULL)
{
perror("fopen:");
return;
}
//循环读取文件数据
peoInfo info;
while (fread(&info, sizeof(peoInfo), 1, pf))
{
SLPushBack(con, info);
}
printf("读取数据成功\n");
fclose(pf);
pf = NULL;
}
三、将上述代码做成一个小游戏
效果图如下:
代码如下:
SeqList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "Contact.h"
//首先的创建顺序表的结构
typedef peoInfo SLDataType;
typedef struct SeqList
{
SLDataType* arr;
int size;
int capacity;
}SL;
//1.顺序表的声明
void SLInit(SL* ps);
//2.顺序表的销毁
void SLDestroy(SL* ps);
//3.打印顺序表
void SLPrint(SL* ps);
//4.尾部插入数据
void SLPushBack(SL* ps, SLDataType x);
//5.头插数据
void SLPushFront(SL* ps, int x);
//6.尾部删除数据
void SLPopBack(SL* ps);
//7.头部删除数据
void SLPopFront(SL* ps);
//8.在指定位置之前插入数据
void SLInsert(SL* ps, int pos, int x);
//9.删除指定位置的数据
void SLErase(SL* ps, int pos);
//10.在顺序表中查找指定的数据,如果存在则返回下标,没有则返回一个无效值
void SLFind(SL* ps, int x, int* arr, int* p_count);
SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//1.顺序表的初始化
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
//2.顺序表的销毁
void SLDestroy(SL* ps)
{
if (ps != NULL)
{
free(ps->arr);
ps->arr = NULL;
}
ps->size = ps->capacity = 0;
}
//3.打印顺序表
//void SLPrint(SL* ps)
//{
// for (int i = 0; i < ps->size; i++)
// {
// printf("%d ", ps->arr[i]);
// }
// printf("\n");
//}
//判断空间是否足够
void SLCheckCapicaty(SL* ps)
{
//插之前肯定要判断空间是否足够
if (ps->size == ps->capacity)
{
//首先解决空间为0的问题
int new_capicaty = (ps->capacity == 0 ? 4 : ps->capacity * 2);
SLDataType* tmp = (SLDataType*)realloc(ps->arr, new_capicaty * sizeof(SLDataType));
//此时已经扩容完毕,但是还得判断空间是否开辟成功
if (tmp == NULL)
{
perror("realloc:");
return;
}
ps->arr = tmp;
ps->capacity = new_capicaty;
}
}
//4.尾部插入数据
void SLPushBack(SL* ps, SLDataType x)
{
//首先得先判断传入是否为空指针
assert(ps);
SLCheckCapicaty(ps);
//尾插数据
ps->arr[ps->size] = x;
ps->size++;
}
//5.头插数据
//void SLPushFront(SL* ps, int x)
//{
// //判断传入的指针不能是空指针
// assert(ps);
//
// //判断空间是否足够
// SLCheckCapicaty(ps);
//
// //此时向空间中插入数据,首先得先将顺序表中数据依次往后以一个单元格
// for (int i = ps->size; i > 0; i--)
// {
// ps->arr[i] = ps->arr[i - 1];
// }
// //头部插入数据
// ps->arr[0] = x;
// ps->size++;
//
//}
//6.尾部删除数据
void SLPopBack(SL* ps)
{
//首先还是得先判断指针
assert(ps);
ps->size--;
}
//7.头部删除数据
void SLPopFront(SL* ps)
{
assert(ps);
for (int i = 0; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//8.在指定位置之前插入数据
//void SLInsert(SL* ps, int pos, int x)
//{
// assert(ps);
// //首先得先判断空间是否足够
// SLCheckCapicaty(ps);
// //在指定位置插入数据
// for (int i = ps->size; i > pos; i--)
// {
// ps->arr[i] = ps->arr[i - 1];
// }
// //此时开始插入数据
// ps->arr[pos] = x;
// ps->size++;
//}
//9.删除指定位置的数据
void SLErase(SL* ps, int pos)
{
assert(ps);
for (int i = pos; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
//10.在顺序表中查找指定的数据,如果存在则返回下标,没有则返回一个无效值
//void SLFind(SL* ps, int x, int* arr, int* p_count)
//{
// assert(ps);
// assert(ps->size);
// for (int i = 0; i < ps->size; i++)
// {
// if (ps->arr[i] == x)
// {
// /*arr[*p_count] = i;*/
// *(arr + *p_count) = i;
// *p_count++;
// }
// }
//}
Contact.h
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
//定义联系人的数据结构
//姓名, 性别,年龄 , 电话 , 地址
typedef struct personInfo
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}peoInfo;
//首先得先给通讯录起个名字
typedef struct SeqList Contact;
//1.通讯录的初始化
void ContactInit(Contact* con);
//2.通讯录的销毁
void ContactDestroy(Contact* con);
//3.展示通讯录数据
void ShowContact(Contact* con);
//4.通讯录添加数据
void ContactAdd(Contact* con);
//5.通讯录删除数据
void ContactDel(Contact* con);
//6.通讯录修改数据
void ContactModify(Contact* con);
//7.通讯录的查找
void ContactFind(Contact * con);
//8.将通讯录的数据写入到文件中
void SaveContact(Contact* con);
//9.从文件中读取数据到通讯录中
void LoadContact(Contact* con);
Contact.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
#include "SeqList.h"
//1.通讯录的初始化
void ContactInit(Contact* con)
{
//实际上就是对顺序表进行初始化
SLInit(con);
}
//2.通讯录的销毁
void ContactDestroy(Contact* con)
{
SLDestroy(con); //同上
}
//3. 展示通讯录数据
void ShowContact(Contact* con)
{
//表头:姓名 性别 年龄 电话 地址
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
//遍历通讯录,按照格式打印每个联系人的数据
for (int i = 0; i < con->size; i++)
{
printf("%3s %4s %4d %4s %4s\n",
con->arr[i].name,
con->arr[i].gender,
con->arr[i].age,
con->arr[i].tel,
con->arr[i].addr
);
}
}
//4.通讯录添加数据
void ContactAdd(Contact* con)
{
//首先我们得获取用户输入的内容:姓名+性别+年龄+电话+地址
peoInfo Info;
printf("请输入你想要添加联系人的姓名:");
scanf("%s", Info.name);
printf("请输入你想要添加联系人的性别:");
scanf("%s", Info.gender);
printf("请输入你想要添加联系人的年龄:");
scanf("%d", &Info.age);
printf("请输入你想要添加联系人的电话:");
scanf("%s", Info.tel);
printf("请输入你想要添加联系人的地址:");
scanf("%s", Info.addr);
//获取到数据之后,就需要往通讯录中写入
SLPushBack(con, Info);
}
int FindbyName(Contact* con, char name[])
{
for (int i = 0; i < con->size; i++)
{
if (strcmp(name, con->arr[i].name) == 0)
{
printf("找到了下标为:%d\n", i);
return i;
}
}
return -1;
}
//5.通讯录删除数据
void ContactDel(Contact* con)
{
//想要删除,就需要将他给找出来
printf("请输入你想要删除联系人得姓名:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindbyName(con, name);
if (ret < 0)
{
printf("要删除得联系人数据不存在!\n");
return;
}
SLErase(con, ret);
printf("删除成功!\n");
}
//6.通讯录修改数据
void ContactModify(Contact* con)
{
printf("请输入你想要修改联系人的姓名:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindbyName(con, name);
if (ret < 0)
{
printf("抱歉,通讯录中没有这个联系人!\n");
return;
}
printf("请输入你想修改后联系人的姓名:");
scanf("%s", con->arr[ret].name);
printf("请输入你想修改后联系人的性别:");
scanf("%s", con->arr[ret].gender);
printf("请输入你想修改后联系人的年龄:");
scanf("%d", &con->arr[ret].age);
printf("请输入你想修改后联系人的电话:");
scanf("%s", con->arr[ret].tel);
printf("请输入你想修改后联系人的地址:");
scanf("%s", con->arr[ret].addr);
}
//7.查找联系人的信息
void ContactFind(Contact* con)
{
printf("请输入你想要查找联系人的姓名:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindbyName(con, name);
if (ret < 0)
{
printf("没有这个联系人的信息!\n");
return;
}
//开始打印
printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%3s %4s %4d %4s %4s\n",
con->arr[ret].name,
con->arr[ret].gender,
con->arr[ret].age,
con->arr[ret].tel,
con->arr[ret].addr
);
}
//9.从文件中读取数据到通讯录中
void LoadContact(Contact* con)
{
FILE* pf = fopen("contact.txt", "rb");
if (pf == NULL)
{
perror("fopen:");
return;
}
//循环读取文件数据
peoInfo info;
while (fread(&info, sizeof(peoInfo), 1, pf))
{
SLPushBack(con, info);
}
printf("读取数据成功\n");
fclose(pf);
pf = NULL;
}
//8.将通讯录的数据写入到文件中
void SaveContact(Contact* con)
{
FILE* pf = fopen("contact.txt", "wb");
assert(pf);
for (int i = 0; i < con->size; i++)
{
fwrite(con->arr + i, sizeof(peoInfo), 1, pf);
}
printf("通讯录数据保存成功!\n");
fclose(pf);
pf = NULL;
}
test.c文章来源:https://www.toymoban.com/news/detail-857765.html
void menu()
{
printf("****************通讯录******************\n");
printf("******1.增加联系人 2.删除联系人******\n");
printf("******3.修改联系人 4.查找联系人******\n");
printf("******5.展示联系人 0.退出程序********\n");
printf("****************************************\n");
printf("****************************************\n");
}
int main()
{
/*Contact_test01();*/
int input = 0;
Contact con;
//初始化
ContactInit(&con);
do
{
menu();
printf("请输入你想要进行的操作:");
scanf("%d", &input);
switch (input)
{
case 1:
ContactAdd(&con);
break;
case 2:
ContactDel(&con);
break;
case 3:
ContactModify(&con);
break;
case 4:
ContactFind(&con);
break;
case 5:
ShowContact(&con);
break;
default:
break;
}
} while (input);
//销毁
ContactDestroy(&con);
return 0;
}
完文章来源地址https://www.toymoban.com/news/detail-857765.html
到了这里,关于数据结构从入门到实战——顺序表的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!