C语言实现一个静态通讯录

本文介绍了用C语言代码实现静态通讯录的编写。先说明了基本流程,包括安装Visual Studio 2022编译器、创建新项目及相关文件。接着讲解思路,如编写菜单界面、声明结构体、初始化通讯录等,还阐述了增删改查等功能的实现。最后展示了总代码。

一、问题描述及文章声明

1. 问题描述

通过C语言代码实现一个静态通讯录的编写

2. 文章声明

如果您想系统学会如何编写静态通讯录程序,请先认真理解思路讲解中的整体思路分析,而后按照每个步骤认真学习,相信您会有所收获。
如果您只是想复制代码,直接跳到代码实现步骤即可。

二、基本流程

1. 在电脑安装Visual Studio 2022等编译器

可于b站查找按照流程

2. 创建一个新项目

(1). 在新建的项目中创建三个文件(如图所示)

test.c文件用于测试通讯录的功能
contact.c文件用于通讯录相关的实现
contact.h文件用于通讯录的相关声明

在这里插入图片描述

三、思路讲解

1. 编写代码时的整体思路分析

当你产生对一件事的想法时,你需要先基本捋清思路,而后在实行的时候不断进行优化,编写三子棋代码也是如此。
首先我们需要明白静态通讯录代码的整体框架。

  1. 当用户打开通讯录时,首先需要有个选择窗口让用户进行选择,因此我们首先需要进行菜单界面的编写。
  2. 而当用户使用通讯录之时,我们需要考虑到用户可能需要的选项,因此我们在菜单界面给用户提供了7个选择,即增、删、改、查、展示、排序、和退出通讯录
  3. 为了对联系人进行更详细的记录以便于用户使用,我们需要先创建一个 PeoInfo 的结构体变量,存储人的信息
  4. 我们需要初步预估用户的所需要存储到通讯录的人数,从而给出一个合理的通讯录空间让用户对联系人进行存储,因此我们需要对通讯录进行初始化
  5. 为了更方便我们看到代码运行结果,因此我们在设置完增加联系人的函数之后,便先设置了打印通讯录中的信息的函数,并在每一段代码书写后运行展示效果,以确保每段代码的正确性。
  6. 当考虑完可能出现的问题后,便可开始进行对对通讯录的编写。

2. 代码的具体分布编写

(1). 菜单函数的设置

下面展示一些 菜单设置代码片
菜单函数设置—— 在test.c文件下
通过设置菜单函数,使用户能够更加直观得观看到通讯录所具备的功能

#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");
}

int main()
{
	int input = 0;//初始化input
	do
	{
		menu();//设置菜单函数
		printf("请选择:>");//提醒用户选择
		scanf("%d", &input);//提醒用户进行选择
		switch (input)//通过选择分支结果调用相应的函数
		{
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 7:
			break;
		}
	} while (input);
}

(2). 相关结构体的声明

相关结构体的设置——在contact.h文件下声明struct PeoInfo()struct Contact()结构体变量并重命名以方便使用
考虑到每个人都具有多种属性,如:年龄、性别、电话等,因此我们定义一个人的信息的结构体变量

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

#define MAX		100
#define MAX_NAME 20
#define MAX_SEX  10
#define MAX_TELE 12
#define MAX_ADDR 30

//类型声明
//人的信息
typedef struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[MAX];//存放人的信息
	int count;//统计通讯录实际人数
}Contact;

(3). 通讯录初始化

初始化通讯录函数设置——在contact.h文件下先定义InitContact()函数

#include <assert.h>//需要在contact.c文件下先判断是否为空指针
//[可在该网址查看函数](https://cplusplus.com/reference/cassert/assert/)
#include <string.h>//需要在contact.c文件下使用memset对通讯录内容初始化为0
//[可在该网址查看函数](https://cplusplus.com/reference/cstring/memset/)


void InitContact(Contact* pc);//函数声明

初始化通讯录函数设置—— 在contact.c文件下

void InitContact(Contact* pc)
{
	assert(pc);
	pc->count = 0;//因为是结构体指针,所以用pc->count指向结构体Contact中的结构体变量count
	memset(pc->data, 0, sizeof(pc->data));
}

初始化通讯录函数的调用—— 在test.c文件下

int main()
{
	int input = 0;//初始化input
	Contact con;//通讯录
	//初始化通讯录
	InitContact(&con);
	do {···} while (input);
}

(4). 增加联系人到通讯录中

增加联系人的函数设置——在contact.h文件下先定义AddContact()函数
在设置增加联系人的函数时,由于目前我们所设置的通讯录为静态的,因此我们需要考虑到通讯录是否已经满了的情况,如果已经满了,便直接用 return 跳出该函数

//增加联系人到通讯录中
void AddContact(Contact* pc);

增加联系人的函数设置——在contact.c文件

void AddContact(Contact* pc) 
{
	assert(pc);
	if (pc->count == MAX)
	{
		printf("通讯录已满\n");
	}
	printf("请输入名字:>");
	scanf("%s", pc->data[pc->count].name);//当count为0时,更改结构体数组中第一个结构体变量中的名字
	printf("请输入年龄:>");
	scanf("%d", &(pc->data[pc->count].age));//当count为0时,更改结构体数组中第一个结构体变量中的年龄
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->count].sex);//当count为0时,更改结构体数组中第一个结构体变量中的性别
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->count].tele);//当count为0时,更改结构体数组中第一个结构体变量中的电话
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->count].addr);//当count为0时,更改结构体数组中第一个结构体变量中的地址

	pc->count++;//Contact结构体变量中的总人数加1
	printf("增加成功\n");
}

(4). 打印通讯录中的信息

打印通讯录中的信息的函数设置——在contact.h文件下先定义ShowContact()函数
为了能够通过调试代码来确定每个函数的设置是否正确,因此我们在设置完增加联系人函数之后优先设置打印通讯录中的信息的函数

//打印通讯录中的信息
void ShowContact(Contact* pc);

当我们增加联系人到通讯录中之后,我们需要查看是否增加成功,因此先编写打印通讯中的信息的函数
打印通讯录中的信息的函数设置——在contact.c文件下

void ShowContact(Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s\t%-5s\t%-20s\t%-12s\t%-30s\n","名字", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->count; i++)
	{
		printf("%-20s\t%-5d\t%-20s\t%-12s\t%-30s\n", pc->data[i].name, 
										pc->data[i].age, 
										pc->data[i].sex,
										pc->data[i].tele,
										pc->data[i].addr);
	}
}

(5). 删除指定联系人

删除指定联系人的函数设置——在contact.h文件下先定义DelContact()函数

//删除指定联系人
void DelContact(Contact* pc);

删除指定联系人的函数设置——在contact.c文件下

int FindByName(Contact* pc, char name[])
{
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
	//遍历结构体数组,查看是否有相同的名字,存在则返回该元素的下标
	//也可以用同样的方法通过判断其他信息进行删除
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;
		}
	}
	return -1;

}

void DelContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME] = { 0 };
	if (pc->count == 0)
	{
		printf("通讯录为空,没有信息可以删除\n");
		return;
	}
	printf("请输入要删除人的名字:>");
	scanf("%s", name);
	//删除
	//1.查找
	int pos = FindByName(pc,name);//调用函数判断将要删除的联系人是否存在
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//2.删除
	int i = 0;
	for (i = pos; i < pc->count-1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->count--;//通讯录中总人数在删除后需要减一
	printf("删除成功\n");
}

(6). 查找指定联系人

查找指定联系人的函数设置——在contact.h文件下先定义SearchContact()函数

void SearchContact(Contact* pc);

查找指定联系人的函数设置——在contact.c文件下

void SearchContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME] = { 0 };
	if (pc->count == 0)
	{
		printf("通讯录为空,没有信息可以修改\n");
		return;
	}
	printf("请输入要查找的名字:>");
	scanf("%s", name);
	//查看
	//1.查找
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	//2.打印
	printf("%-20s\t%-5s\t%-10s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
	printf("%-20s\t%-5d\t%-10s\t%-12s\t%-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
}

(6). 修改指定联系人

修改指定联系人的函数设置——在contact.h文件下先定义SearchContact()函数

void SearchContact(Contact* pc);

修改指定联系人的函数设置——在contact.c文件下

 void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME] = { 0 };
	printf("请输入要修改的名字:>");
	scanf("%s", name);
	//1.查找
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	//2.修改
	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].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pos].addr);

	printf("修改成功\n");
}

(6). 排序通讯录中内容

排序通讯录中内容的函数设置——在contact.h文件下先定义SortContact()函数

//排序通讯录中内容
//按照名字来排序
//按照年龄来排序
//...
void SortContact(Contact* pc);

排序通讯录中内容的函数设置——在contact.c文件下

//[qsort的用法](https://cplusplus.com/reference/cstdlib/qsort/)
int cmp_peo_by_name(const void* e1,const void*e2)//设置比较函数
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}


void SortContact(Contact* pc)
{
	assert(pc);
	qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_peo_by_name);
	printf("排序成功\n");
}

(7). 效果展示

部分效果展示

四、代码实现

test.c总代码展示

#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");
}

int main()
{
	int input = 0;//初始化input
	Contact con;//通讯录
	//初始化通讯录
	InitContact(&con);
	do
	{
		menu();//设置菜单函数
		printf("请选择:>");//提醒用户选择
		scanf("%d", &input);//提醒用户进行选择
		switch (input)//通过选择分支结果调用相应的函数
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			SearchContact(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 6:
			SortContact(&con);
			break;
		case 7:
			break;
		}
	} while (input);
}

contact.c总代码展示

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

void InitContact(Contact* pc)
{
	assert(pc);
	pc->count = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

void AddContact(Contact* pc) 
{
	assert(pc);
	if (pc->count == MAX)
	{
		printf("通讯录已满\n");
	}
	printf("请输入名字:>");
	scanf("%s", pc->data[pc->count].name);//当count为0时,更改结构体数组中第一个结构体变量中的名字
	printf("请输入年龄:>");
	scanf("%d", &(pc->data[pc->count].age));//当count为0时,更改结构体数组中第一个结构体变量中的年龄
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->count].sex);//当count为0时,更改结构体数组中第一个结构体变量中的性别
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->count].tele);//当count为0时,更改结构体数组中第一个结构体变量中的电话
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->count].addr);//当count为0时,更改结构体数组中第一个结构体变量中的地址

	pc->count++;//Contact结构体变量中的总人数加1
	printf("增加成功\n");
}

void ShowContact(Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s\t%-5s\t%-20s\t%-12s\t%-30s\n","名字", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pc->count; i++)
	{
		printf("%-20s\t%-5d\t%-20s\t%-12s\t%-30s\n", pc->data[i].name, 
										pc->data[i].age, 
										pc->data[i].sex,
										pc->data[i].tele,
										pc->data[i].addr);
	}
}

int FindByName(Contact* pc, char name[])
{
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;
		}
	}
	return -1;

}

void DelContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME] = { 0 };
	if (pc->count == 0)
	{
		printf("通讯录为空,没有信息可以删除\n");
		return;
	}
	printf("请输入要删除人的名字:>");
	scanf("%s", name);
	//删除
	//1.查找
	int pos = FindByName(pc,name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//2.删除
	int i = 0;
	for (i = pos; i < pc->count-1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->count--;
	printf("删除成功\n");
	
}

void SearchContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME] = { 0 };
	if (pc->count == 0)
	{
		printf("通讯录为空,没有信息可以修改\n");
		return;
	}
	printf("请输入要查找的名字:>");
	scanf("%s", name);
	//查看
	//1.查找
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	//2.打印
	printf("%-20s\t%-5s\t%-10s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
	printf("%-20s\t%-5d\t%-10s\t%-12s\t%-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);
}

void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NAME] = { 0 };
	printf("请输入要修改的名字:>");
	scanf("%s", name);
	//1.查找
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	//2.修改
	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].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pos].addr);

	printf("修改成功\n");

}

int cmp_peo_by_name(const void* e1,const void*e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}


void SortContact(Contact* pc)
{
	assert(pc);
	qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_peo_by_name);
	printf("排序成功\n");
}

contact.h总代码展示

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#define MAX		100
#define MAX_NAME 20
#define MAX_SEX  10
#define MAX_TELE 12
#define MAX_ADDR 30

//类型声明
//人的信息
typedef struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[MAX];//存放人的信息
	int count;//统计通讯录实际人数
}Contact;

void InitContact(Contact* pc);

//增加联系人到通讯录中
void AddContact(Contact* pc);

//打印通讯中的信息
void ShowContact(Contact* pc);

//删除指定联系人
void DelContact(Contact* pc);

//查找指定联系人
void SearchContact(Contact* pc);

//修改指定联系人
void ModifyContact(Contact* pc);

//排序通讯录中内容
//按照名字来排序
//按照年龄来排序
//...
void SortContact(Contact* pc);
06-22
### 得物技术栈及开发者文档分析 得物作为一家专注于潮流商品的电商平台,其技术栈和开发者文档主要围绕电商平台的核心需求展开。以下是对得物技术栈及相关开发资源的详细解析: #### 1. 技术栈概述 得物的技术栈通常会涵盖前端、后端、移动应用开发以及大数据处理等多个领域。以下是可能涉及的主要技术栈[^3]: - **前端开发**: 前端技术栈可能包括现代框架如 React 或 Vue.js,用于构建高效、响应式的用户界面。此外,还会使用 Webpack 等工具进行模块化打包和优化。 - **后端开发**: 后端技术栈可能采用 Java Spring Boot 或 Node.js,以支持高并发和分布式架构。数据库方面,MySQL 和 Redis 是常见的选择,分别用于关系型数据存储和缓存管理。 - **移动应用开发**: 得物的移动应用开发可能基于原生技术(如 Swift/Kotlin)或跨平台框架(如 Flutter)。这有助于确保移动端应用的性能和用户体验一致性。 - **大数据云计算**: 在大数据处理方面,得物可能会使用 Hadoop 或 Spark 进行数据挖掘和分析。同时,依托云服务提供商(如阿里云或腾讯云),实现弹性扩展和资源优化。 #### 2. 开发者文档分析 类似于引用中提到的 Adobe 开发者文档模板[^2],得物也可能提供一套完整的开发者文档体系,以支持内部团队协作和外部开发者接入。以下是开发者文档可能包含的内容: - **API 文档**: 提供 RESTful API 或 GraphQL 的详细说明,帮助开发者快速集成得物的功能模块,例如商品搜索、订单管理等。 - **SDK 集成指南**: 针对不同平台(如 iOS、Android 或 Web)提供 SDK 下载和集成教程,简化第三方应用的开发流程。 - **技术博客**: 分享得物在技术实践中的经验成果,例如如何优化图片加载速度、提升应用性能等。 - **开源项目**: 得物可能将部分技术成果开源,供社区开发者学习和贡献。这不仅有助于提升品牌形象,还能吸引更多优秀人才加入。 #### 3. 示例代码 以下是一个简单的示例代码,展示如何通过 RESTful API 调用得物的商品搜索功能(假设接口已存在): ```python import requests def search_items(keyword, page=1): url = "https://api.dewu.com/v1/items/search" headers = { "Authorization": "Bearer YOUR_ACCESS_TOKEN", "Content-Type": "application/json" } params = { "keyword": keyword, "page": page, "size": 10 } response = requests.get(url, headers=headers, params=params) if response.status_code == 200: return response.json() else: return {"error": "Failed to fetch data"} # 调用示例 result = search_items("Air Jordan", page=1) print(result) ``` 此代码片段展示了如何通过 Python 请求得物的 API,并获取指定关键词的商品列表。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值