首页 > 其他分享 >C语言_通讯录

C语言_通讯录

时间:2024-10-19 22:50:02浏览次数:3  
标签:sz name int 联系人 C语言 pc 通讯录 printf

引言:当我们C语言语法大部分都学习完的情况下,可以尝试一些项目来提升自己,比如下面的这个通讯录。

玩法介绍:我们需要对通讯录里面的个人信息进行增删查改以及排序等操作

技能要求:学习完大部分的C语言语法知识。

接下来我将创建三个文件:具备函数声明宏定义、所需库函数头文件以及还有两个函数实现的源文件以及测试项目逻辑的源文件

文件名如下:

  • Contact.c (通讯录函数实现的源文件)
  • Contact.h(通讯录的头文件)
  • test.c(项目逻辑测试的源文件)

项目大纲

在正式写项目之前,我们要在脑海里面有一个对项目的大体流程。

  • 项目的基本逻辑
  • 创建通讯录(能容纳100个个人信息的通讯录以及记载当前存储通讯录个数)
  • 初始化通讯录信息
  • 添加联系人
  • 全部显示联系人
  • 删除联系人
  • 查找联系人
  • 修改联系人
  • 模拟快排并排序通讯录信息

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("******************************\n");
}

void test()
{
	int input = 0;
	Contact Con;
	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 SHOW:
				ShowContact(&Con);
				break;
			case SORT:
				Bubble_sort(&(Con.data[0]), MAX, sizeof(Con.data[0]), cmp_by_name);
				break;
			case EXIT:
				break;
			default:
				printf("输入有误,请重新输入!!!\n");
				break;
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}

Contact.c(通讯录函数实现的源文件)

初始化通讯录

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc != NULL);
	//不借助memset,实现手搓对通讯录进行初始化
	int size = sizeof(pc->data);
	char* ptr = pc->data;
	int i = 0;
	for (i = 0; i < size; i++)
	{
		ptr[i] = 0;
	}
	pc->sz = 0;
}

添加联系人

//清空缓冲区
void Clear_Buffer_area()
{
	while (getchar() != '\n')
	{
		;
	}
}

//添加联系人
void AddContact(Contact* pc)
{
	assert(pc != NULL);
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加联系人!!!\n");
		return;
	}
	printf("请输入你的名字:");
	scanf("%s", pc->data[pc->sz].name);
	//字符串输入会在缓冲区留下'\n'
	//所以我们在输入完字符串的时候做一个清空缓冲区的操作
	Clear_Buffer_area();
	printf("请输入你的年龄:");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入你的性别:");
	scanf("%s", pc->data[pc->sz].sex);
	Clear_Buffer_area();
	printf("请输入你的电话:");
	scanf("%s", pc->data[pc->sz].tele);
	Clear_Buffer_area();
	printf("请输入你的地址:");
	scanf("%s", pc->data[pc->sz].addr);
	Clear_Buffer_area();
	pc->sz++;
	printf("成功添加联系人!!!\n");
}

全部显示联系人

void title()
{
	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
}

//显示全部联系人
void ShowContact(const Contact* pc)
{
	assert(pc != NULL);
	int i = 0;
	title();
	if (pc->sz == 0)
	{
		printf("-> 暂时未添加联系人!!!<-\n");
	}
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s\t%-4d\t%-5s\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 my_strcmp(char* str1, char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

//查找通讯录中指定的联系人
int Find_Name(Contact* pc, char* name)
{
	int i = 0;
	//匹配需要查找的联系人名字
	for (i = 0; i < pc->sz; i++)
	{
		if (my_strcmp(name, pc->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void DelContact(Contact* pc)
{
	assert(pc != NULL);
	if (pc->sz == 0)
	{
		printf("暂未有联系人,无需删除!!!\n");
		return;
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入需要删除的联系人名字:");
	scanf("%s", name);
	int pos = Find_Name(pc, name);
	//判断有没有找到联系人
	if (pos == -1)
	{
		printf("没有找到该联系人!!!\n");
		return;
	}
	//判断是不是最后一个联系人
	if (pos == pc->sz - 1)
	{
		//直接进行对存储的个数 - 1操作,不需要覆盖。
		pc->sz--;
		printf("成功删除联系人!!!\n");
		return;
	}
	//删除联系人
	int i = 0;
	for (i = pos; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	printf("成功删除联系人!!!\n");
	//删除完了还需要进行对存储个数 - 1操作。
	pc->sz--;
}

查找联系人

//手搓字符串比对函数
int my_strcmp(char* str1, char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

//查找通讯录中指定的联系人
int Find_Name(Contact* pc, char* name)
{
	int i = 0;
	//匹配需要查找的联系人名字
	for (i = 0; i < pc->sz; i++)
	{
		if (my_strcmp(name, pc->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}

//标题
void title()
{
	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
}

//查找联系人
void SearchContact(const Contact* pc)
{
	assert(pc != NULL);
	if (pc->sz == 0)
	{
		printf("还没有添加联系人!!!\n");
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入你要查找的联系人名字:");
	scanf("%s", name);
	int pos = Find_Name(pc, name);
	if (pos == -1)
	{
		printf("暂未查找到该联系人!!!\n");
		return;
	}
	else
	{
		title();
		printf("%-10s\t%-4d\t%-5s\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);
	}
}

修改联系人信息

//手搓字符串比对函数
int my_strcmp(char* str1, char* str2)
{
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

//查找通讯录中指定的联系人
int Find_Name(Contact* pc, char* name)
{
	int i = 0;
	//匹配需要查找的联系人名字
	for (i = 0; i < pc->sz; i++)
	{
		if (my_strcmp(name, pc->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}

void menu_modify()
{
	printf("*******************************\n");
	printf("***** 1.name      2.age   *****\n");
	printf("***** 3.sex       4.tele  *****\n");
	printf("***** 5.addr      0.exit  *****\n");
	printf("*******************************\n");
}

//修改联系人信息
void ModifyContact(Contact* pc)
{
	assert(pc != NULL);
	if (pc->sz == 0)
	{
		printf("还没有添加联系人!!!\n");
	}
	char name[MAX_NAME] = { 0 };
	printf("请输入你要修改的联系人名字:");
	scanf("%s", name);
	int pos = Find_Name(pc, name);
	if (pos == -1)
	{
		printf("暂未查找到该联系人!!!\n");
		return;
	}
	else
	{
		int input = 0;
		do
		{
			menu_modify();
			printf("请输入你需要修改的信息:");
			scanf("%d", &input);
			switch (input)
			{
			case 1:
				printf("请输入你的名字:");
				scanf("%s", pc->data[pos].name);
				printf("修改成功!!!\n");
				break;
			case 2:
				printf("请输入你的年龄:");
				scanf("%d", &(pc->data[pos].age));
				printf("修改成功!!!\n");
				break;
			case 3:
				printf("请输入你的性别:");
				scanf("%s", pc->data[pos].sex);
				printf("修改成功!!!\n");
				break;
			case 4:
				printf("请输入你的电话:");
				scanf("%s", pc->data[pos].tele);
				printf("修改成功!!!\n");
				break;
			case 5:
				printf("请输入你的地址:");
				scanf("%s", pc->data[pos].addr);
				printf("修改成功!!!\n");
				break;
			case 0:
				printf("退出选项!!!\n");
				break;
			default:
				printf("输入有误,请重新输入!!!\n");
				break;
			}
		} while (input);
	}
}

模拟快排并排序通讯录信息

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//因为是字符串,所以我们通过my_strcmp进行比对大小
int cmp_by_name(void* pf1, void* pf2)
{
	return my_strcmp(((People_Info*)pf1)->name, ((People_Info*)pf2)->name);
}

//两数交换
void Swap(char* buf1, char* buf2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *(buf1 + i);
		*(buf1 + i) = *(buf2 + i);
		*(buf2 + i) = tmp;
	}
}

void Bubble_sort(People_Info* stu, int num, int sz, int (*cmp_by_name)(void* pf1, void* pf2))
{
	int i = 0;
	for (i = 0; i < num; i++)
	{
		int j = 0;
		for (j = 0; j < num - i - 1; j++)
		{
			//通过我们自己创造的函数进行比对结果
			if (cmp_by_name((char*)stu + j * sz, (char*)stu + (j + 1) * sz) < 0)
			{
				Swap((char*)stu + j * sz, (char*)stu + (j + 1) * sz, sz);
			}
		}
	}
}

输出结果:

在这里插入图片描述

Contact.h(通讯录头文件)

通讯录头文件

#pragma once

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

#define MAX 20
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

enum OPTION
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};

typedef struct People_Info People_Info;
struct People_Info
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
};

typedef struct Contact Contact;
struct Contact
{
	People_Info data[MAX];
	int sz;
};

//初始化通讯录
void InitContact(Contact* Con);

//添加联系人
void AddContact(Contact* Con);

//显示全部联系人
void ShowContact(const Contact* Con);

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

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

//修改指定联系人信息
void ModifyContact(Contact* Con);

//字符串比较函数
int my_strcmp(char* str1, char* str2);

//手搓快排
void Bubble_sort(People_Info* stu, int num, int sz, int (*cmp_by_name)(void* pf1, void* pf2));

//声明cmp_by_name
int cmp_by_name(void* pf1, void* pf2);

总结:

该项目主要功能就是对通讯录内的信息完成增删查改以及模拟快排并排序通讯录信息功能,当你学习完大部分内容的情况下,该项目还是非常适合巩固自己所学的知识。

如果该项目对你有帮助的话,不妨留下一个赞吧。

本章完~

标签:sz,name,int,联系人,C语言,pc,通讯录,printf
From: https://blog.csdn.net/m0_74445256/article/details/143064142

相关文章

  • 【趣学C语言和数据结构100例】
    【趣学C语言和数据结构100例】问题描述在带头结点的单链表中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法以实现上述操作。试编写在带头结点的单链表中寻找一个最小值结点的高效算法(假设该结点唯一)设在一个带表头结点的单链表中,所有结点......
  • 数据结构C语言|队列相关
    队列普通队列与循环队列:结构体初始化队列判断队空入队出队检查队满循环队列链式队列:链式队列链式队列结构初始化判断是否为空入队出队遍历全部代码展示结构体typedefintElemType;#defineMaxSize10typedefstruct{ ElemTypedata[MaxSize]; //用静态......
  • C语言解决约瑟夫环(PTA链表)
    题意:就是N个人围成一个圈(想到循环),开始报数,报到一个指定的数p,则这个人出局,后延,比如本题的样例,第三个人报了3,则第四个人继续从1开始报数,一直循环下去,第七个人报完之后,再到第一个人,直到只剩下一个人,那么下一个出局的只剩下这个人。解题思路:我们看到,最后一个人报数之后,又回到了......
  • C语言 【操作符(上)】
        最开始提到C语言操作符,我还是有一些不屑的,这玩意有啥学的呀?今天静下心来阅读学习了一下操作符部分的知识,这部分还真得认真学习学习!下面我将操作符中一些比较关键的点进行罗列和详细说明。一来帮助我加深理解,二来希望能帮助到有缘点击进来的读者。1、算术操作符:+ ......
  • C语言经典游戏代码大全(珍藏版)
    前言发现很多朋友都想要一些小项目来练手,却找不到从哪里寻找,给大家整理了游戏项目开发源代码汇总。一、最经典游戏之俄罗斯方块#include<iostream>#include<math.h>#include<Windows.h>#include<conio.h>#include<ctime>usingnamespacestd; enumDIR{   UP......
  • Linux C语言TCP协议实战
    文章目录1.TCP简介2.搭建框图3.相关函数介绍3.1socket函数3.2bind函数3.3listen函数3.4accept函数3.5connect函数3.6send函数3.7recv函数3.8其他函数4.实战4.1一对一模型4.1.1server.c4.1.2client.c4.1.3终端结果4.2多进程模型4.2.1server.c4.2.2cl......
  • 汉诺塔问题和青蛙跳台阶问题(c语言)
     这俩道题都是利用到了函数递归的思想,其中汉诺塔问题较难理解,青蛙跳台阶则较简单汉诺塔问题题述:设有三根柱子分别时A,B,C,在A柱子上放着n个盘子,每个盘子大小不一样,从下往上盘子大小依次减小,要求将A柱子上的盘子移动到C柱,且不改变盘子顺序(由大往小排序)。规则:1.一次只能......
  • 【C语言】动态内存管理(上)
    本篇博客将讲解以下知识点:(1)为什么要有动态内存分配(2)malloc和free1、为什么要有动态内存分配我们已经掌握的内存开辟方式有:intval=40;//向内存中申请4个字节空间存储valchararr[10];//向内存申请10个字节空间 上述的开辟空间的方式有两个特点:(1)空间的开辟......
  • 【C语言】strncat、strncmp、strstr函数讲解
    本篇博客将讲解函数:strncat、strncmp、strstr函数注意:使用strncat、strncmp、strstr函数时要包含头文件:string.h1、strncat函数的使用(是从目标空间中第一个的‘\0’位置开始追加的)strncat函数原型: char*   strncat(char*destination,  const char* sourc......
  • c语言语法(76-79)10.19
    一.定义数组1.数组定义:2.数组的特点:补:数组内部的特点:左值是读,右值是写3.数组的下标:从0开始计数4.有效的下标范围:从0开始到数组的大小-1的范围当出现以下标志表示数组的下标越界:eg.此代码中的10超过了有效下标9,所以无效会报错二.数组的例子1.eg题目:代码:三.......