佬,速速进来观看你的专属通讯录(静态版本)


前言

通讯录是我们日常生活中都会用到的东西,而对于刚接触C语言不久的小萌新们来说,又有许多的知识点要了解才能写出专属与自己的通讯录。
通讯录主要有三大功能
1.联系人的存储
2.联系人的查找与现实
3.联系人的增删查改


一、三大库的建立

对很多新手来说,无论是使用keil编译还是我们本文所用的VS系列编译器,都只会建立一个test.c文件。今天我带大家一步步的剖析常用项目的工作过程

1.Contact.h文件

该模块主要以各类库函数的引用与声明,便于我们开发。极大减少了多次声明Contact.c与Text.c中各类的声明次数。
.h类文件使得函数的作用域从函数声明的位置开始,而不是函数定义的位置。好的习惯是成功的一半,希望大家可以规范建立,为自己打下良好的基础。
同时.h还可以对一个软件包来说可以提供一个给外界的人接口(例如:studio.h、string.h、assert.h等我们通讯录需要饮用的库函数一样)。

1.1 各类库函数

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
#include<assert.h>
#include <stdlib.h>

制作通讯录要用到的库函数

1.2 宏定义、自定义结构体、以及必要函数的声明

#define MAX 11

增强程序的可读性。
宏定义方便我们随时更改一些常量值。
宏定义的展开是在程序的预处理阶段完成的,无需运行时分配内存,能够部分实现函数的功能,却没有函数调用的压栈、弹栈开销,效率较高。

struct strtact
{
	char name[MAX];
	char sex[MAX];
	char tele[MAX];
	char age[MAX];
	char adde[MAX];
};
struct Contact
{
	int sz;
	struct strtact data[MAX];
};

此处是通讯录所用到的自定义结构体,分别定义了一个人name、sex、tele、age、以及adde,如果有对结构体的定义不清晰的同学,可以去看我之前对结构体总结的文章。

//初始化通讯录
void zeroContact(struct Contact* pc);
//增加指定联系人
void pushContact(struct Contact* pc);
//删除指定联系人
void delContact(struct Contact* pc);
//查找指定联系人
void findContact(const struct Contact* pc);
//修改指定联系人
void reviseContact(struct Contact* pc)
//打印联系人
void showContact(struct Contact* pc)

函数的声明

2.Contact.c文件

该模块主要以各类函数的应用而存在。
当我们完成一个大项目的时候,其中函数不可或缺甚至是最重要的东西,分类、选择、嵌套种种一般这个时候我们程序的可读性就会逐渐降低。这也是为啥么我们要建立多个文件进行职能的分配从而更好完成项目。

2.1功能函数的声明

初始化通讯录
主要使用函数 void * memset ( void * ptr, int value, size_t num );
memset是计算机中C/C++语言初始化函数。 作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。 函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。 memset:作用是在一段内存块中填充某个给定的值,它是对较大的 结构体 或 数组 进行清零操作的一种最快方法 。

//初始化通讯录
void zeroContact(struct Contact* pc)
{
	pc->sz = 0;
	memset(pc->data, 0, MAX*sizeof(struct strtact));
}

输入新的联系人

//增加一个联系人
void pushContact(struct Contact* pc)
{
	assert(pc);
	printf("请输入姓名:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:"); 
	scanf("%s",pc->data[pc->sz].sex);
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pc->sz].adde);
	printf("请输入年龄:");
	scanf("%s", pc->data[pc->sz].age);
	printf("成功保存联系人。\n");
	printf("\n");
	pc->sz++;
}

查找指定联系人

//查找指定联系人,会提示我们输入要查找的人名
//若不存在,会返回查无此人
void findContact(const struct Contact* pc)
{
	int i = 0;
	char name[MAX];
	printf("请输入要查找的人名:");
	scanf("%s", name);
	int ret1 = FindContact(pc, name);
	if (ret1 == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		printf("找到了\n");
	}
}

查找时我们用到了函数 int strcmp ( const char * str1, const char * str2 );
从第一个字符开始比较,如果到最后两个字符串完全相同,则strcmp函数输出的值为0;若开始出现不同的字符,根据这个字符ASCII码进行比较,若字符串1的ASSCII值大于字符串2则输出大于零的数反之。
//若实在不理解可以去我之前的文章C常用函数解析

//底层查找不返回
//因为无论是查找、删除等功能都要输入指定的联系人所以方便程序的可读性而存在
int FindContact(const struct Contact* pc, char* name)
{
	int i = 0;
	char* ps = name;
	for (i = 0; i < pc->sz; i++)
	{	//strcmp函数,通过比较我们才能得知要改的联系人是否存在与否
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

删除指定联系人

//删除指定的联系人
void delContact(struct Contact* pc)
{
	char name[MAX];
	printf("请输入要删除的人名:");
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		for (int j = 0; j < pc->sz - 1; j++)
		{
			if (j == ret)
			{
				pc->data[j] = pc->data[j + 1];
			}
		}
		pc->sz--;
		printf("成功删除\n");
	}
}

打印之前已经输入的联系人,已经导航栏

//打印出已经输入的联系人
void showContact(struct Contact* pc)
{
	assert(pc);
	int i = 0;
	//为方便阅读,下行打印的是通讯录的框架,各种信息的导航栏目。
	printf("%-11s\t%-11s\t%-11s\t%-11s\t%-11s\t%-11s\n", "信息", "姓名", "性别", "电话", "年龄","住址");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-11d\t%-11s\t%-11s\t%-11s\t%-11s\t%-11s\n",i,pc->data[i].name,
			pc->data[i].sex, 
			pc->data[i].tele, 
			pc->data[i].age, 
			pc->data[i].adde);
	}
	printf("\n");
}

修改指定联系人的信息

//修改指定联系人
void reviseContact(struct Contact* pc)
{
	assert(pc);

	char name[MAX] = { 0 };
	printf("请输入要修改的联系人姓名:");
	scanf("%s", name);
	int ret2 = FindContactByName(pc, name);
	if (ret2 == -1)
	{
		printf("联系人不存在!!!\n");
		return;
	}
	else
	{
		printf("请输入新的联系人姓名:");
		scanf("%s", pc->data[ret2].name);
		printf("请输入新的联系人年龄:");
		scanf("%s", &pc->data[ret2].age);
		printf("请输入新的联系人性别:");
		scanf("%s", pc->data[ret2].sex);
		printf("请输入新的联系人电话:");
		scanf("%s", pc->data[ret2].tele);
		printf("请输入新的联系人住址:");
		scanf("%s", pc->data[ret2].adde);
	}

}

3.test.c文件

这是我们新手熟悉的东西,我们梦开始的地方~
主要职责是存放主函数(main)以及主程序种种而存在。

3.1 main函数

主函数

int main()
{	//进入通讯录
	text();
	return 0;
}

菜单

void menu()
{	//菜单
	printf("***********************\n");
	printf("*****1.Push 2.Find*****\n");
	printf("*****3.Del  4.revise***\n");
	printf("*****5.show 0.vim******\n");
	printf("***********************\n");
}

通讯录实现主体

//通讯录主体
void text()
{
	struct Contact ss;
	//初始化通讯录
	zeroContact(&ss);
	int input;
	do
	{
		menu();
		printf("\n");
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			pushContact(&ss);
			break;
		case 2:
			findContact(&ss);
			break;
		case 3:
			delContact(&ss);
			break;
		case 4:
			reviseContact(&ss);
			break;
		case 5:
			showContact(&ss);
			break;
		case 0:
			printf("成功退出\n");
			break;
		default:
			printf("输入错误请重新输入\n");
			break;
		}
	} while (input);
}

二、完整文件

1.声明模块

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
#include<assert.h>
#include <stdlib.h>
#define MAX 11


//初始化通讯录//
void zeroContact(struct Contact* pc);

//增加存些联系人//

//删除指定联系人//

//查找指定联系人//

//修改指定联系人//

//打印指定联系人//
struct strtact
{
	char name[MAX];
	char sex[MAX];
	char tele[MAX];
	char age[MAX];
	char adde[MAX];
};
struct Contact
{
	int sz;
	struct strtact data[MAX];
};

2.函数模块

#include"Contact.h"

void zeroContact(struct Contact* pc)
{
	pc->sz = 0;
	memset(pc->data, 0, MAX*sizeof(struct strtact));
}
void pushContact(struct Contact* pc)
{
	assert(pc);
	printf("请输入姓名:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:"); 
	scanf("%s",pc->data[pc->sz].sex);
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pc->sz].adde);
	printf("请输入年龄:");
	scanf("%s", pc->data[pc->sz].age);
	printf("成功保存联系人。\n");
	printf("\n");
	pc->sz++;
}
void findContact(const struct Contact* pc)
{
	int i = 0;
	char name[MAX];
	printf("请输入要查找的人名:");
	scanf("%s", name);
	int ret1 = FindContact(pc, name);
	if (ret1 == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		printf("找到了\n");
	}
}

int FindContact(const struct Contact* pc, char* name)
{
	int i = 0;
	char* ps = name;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void delContact(struct Contact* pc)
{
	char name[MAX];
	printf("请输入要删除的人名:");
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		for (int j = 0; j < pc->sz - 1; j++)
		{
			if (j == ret)
			{
				pc->data[j] = pc->data[j + 1];
			}
		}
		pc->sz--;
		printf("成功删除\n");
	}
}
void showContact(struct Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-11s\t%-11s\t%-11s\t%-11s\t%-11s\t%-11s\n", "信息", "姓名", "性别", "电话", "年龄","住址");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-11d\t%-11s\t%-11s\t%-11s\t%-11s\t%-11s\n",i,pc->data[i].name,
			pc->data[i].sex, 
			pc->data[i].tele, 
			pc->data[i].age, 
			pc->data[i].adde);
	}
	printf("\n");
}

void reviseContact(struct Contact* pc)
{
	assert(pc);

	char name[MAX] = { 0 };
	printf("请输入要修改的联系人姓名:");
	scanf("%s", name);
	int ret2 = FindContact(pc, name);
	if (ret2 == -1)
	{
		printf("联系人不存在!!!\n");
		return;
	}
	else
	{
		printf("请输入新的联系人姓名:");
		scanf("%s", pc->data[ret2].name);
		printf("请输入新的联系人年龄:");
		scanf("%s", &pc->data[ret2].age);
		printf("请输入新的联系人性别:");
		scanf("%s", pc->data[ret2].sex);
		printf("请输入新的联系人电话:");
		scanf("%s", pc->data[ret2].tele);
		printf("请输入新的联系人住址:");
		scanf("%s", pc->data[ret2].adde);
	}
}
#include"Contact.h"
void menu()
{	//菜单
	printf("***********************\n");
	printf("*****1.Push 2.Find*****\n");
	printf("*****3.Del  4.revise***\n");
	printf("*****5.show 0.vim******\n");
	printf("***********************\n");
}
//通讯录主体
void text()
{
	struct Contact ss;
	//初始化通讯录
	zeroContact(&ss);
	int input;
	do
	{
		menu();
		printf("\n");
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			pushContact(&ss);
			break;
		case 2:
			findContact(&ss);
			break;
		case 3:
			delContact(&ss);
			break;
		case 4:
			reviseContact(&ss);
			break;
		case 5:
			showContact(&ss);
			break;
		case 0:
			printf("成功退出\n");
			break;
		default:
			printf("输入错误请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{	//进入通讯录
	text();
	return 0;
}

3.函数整体

#include"Contact.h"
void menu()
{	//菜单
	printf("***********************\n");
	printf("*****1.Push 2.Find*****\n");
	printf("*****3.Del  4.revise***\n");
	printf("*****5.show 0.vim******\n");
	printf("***********************\n");
}
//通讯录主体
void text()
{
	struct Contact ss;
	//初始化通讯录
	zeroContact(&ss);
	int input;
	do
	{
		menu();
		printf("\n");
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			pushContact(&ss);
			break;
		case 2:
			findContact(&ss);
			break;
		case 3:
			delContact(&ss);
			break;
		case 4:
			reviseContact(&ss);
			break;
		case 5:
			showContact(&ss);
			break;
		case 0:
			printf("成功退出\n");
			break;
		default:
			printf("输入错误请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{	//进入通讯录
	text();
	return 0;
}

//Contect.c

#include"Contact.h"
void zeroContact(struct Contact* pc)
{
	pc->sz = 0;
	memset(pc->data, 0, MAX*sizeof(struct strtact));
}
void pushContact(struct Contact* pc)
{
	assert(pc);
	printf("请输入姓名:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:"); 
	scanf("%s",pc->data[pc->sz].sex);
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pc->sz].adde);
	printf("请输入年龄:");
	scanf("%s", pc->data[pc->sz].age);
	printf("成功保存联系人。\n");
	printf("\n");
	pc->sz++;
}
void findContact(const struct Contact* pc)
{
	int i = 0;
	char name[MAX];
	printf("请输入要查找的人名:");
	scanf("%s", name);
	int ret1 = FindContact(pc, name);
	if (ret1 == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		printf("找到了\n");
	}
}

int FindContact(const struct Contact* pc, char* name)
{
	int i = 0;
	char* ps = name;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void delContact(struct Contact* pc)
{
	char name[MAX];
	printf("请输入要删除的人名:");
	scanf("%s", name);
	int ret = FindContact(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		for (int j = 0; j < pc->sz - 1; j++)
		{
			if (j == ret)
			{
				pc->data[j] = pc->data[j + 1];
			}
		}
		pc->sz--;
		printf("成功删除\n");
	}
}
void showContact(struct Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-11s\t%-11s\t%-11s\t%-11s\t%-11s\t%-11s\n", "信息", "姓名", "性别", "电话", "年龄","住址");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-11d\t%-11s\t%-11s\t%-11s\t%-11s\t%-11s\n",i,pc->data[i].name,
			pc->data[i].sex, 
			pc->data[i].tele, 
			pc->data[i].age, 
			pc->data[i].adde);
	}
	printf("\n");
}

void reviseContact(struct Contact* pc)
{
	assert(pc);

	char name[MAX] = { 0 };
	printf("请输入要修改的联系人姓名:");
	scanf("%s", name);
	int ret2 = FindContact(pc, name);
	if (ret2 == -1)
	{
		printf("联系人不存在!!!\n");
		return;
	}
	else
	{
		printf("请输入新的联系人姓名:");
		scanf("%s", pc->data[ret2].name);
		printf("请输入新的联系人年龄:");
		scanf("%s", &pc->data[ret2].age);
		printf("请输入新的联系人性别:");
		scanf("%s", pc->data[ret2].sex);
		printf("请输入新的联系人电话:");
		scanf("%s", pc->data[ret2].tele);
		printf("请输入新的联系人住址:");
		scanf("%s", pc->data[ret2].adde);
	}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
#include<assert.h>
#include <stdlib.h>
#define MAX 11
//初始化通讯录
void zeroContact(struct Contact* pc);
//增加指定联系人
void pushContact(struct Contact* pc);
//删除指定联系人
void delContact(struct Contact* pc);
//查找指定联系人
void findContact(const struct Contact* pc);
//修改指定联系人
void reviseContact(struct Contact* pc)//打印联系人
void showContact(struct Contact* pc)//自定义结构体
struct strtact
{
	char name[MAX];
	char sex[MAX];
	char tele[MAX];
	char age[MAX];
	char adde[MAX];
};
struct Contact
{
	int sz;
	struct strtact data[MAX];
};

运行结果

打印通讯录
在这里插入图片描述
输入流程
在这里插入图片描述

总结

通讯录的完成是我们学习C语言的一个节点,指针的应用、基础函数的巧用、以及项目的构成。真正自己写出来后就会发先之前很多不懂的东西油然而解。
现在看来难点无非就是几个库函数的应用,只有自己真正上手了才会知其然,知其所以然。
点赞、收藏、评论,为您持续推出详尽的干货。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值