c语言实现一个通讯录

兜兜转转的终于解决了卡了我这么久的问题,
第一步考虑的就错了然后一歪再歪越来越复杂😌思维还是要发散开来每一个环节都考虑上
写的通讯录,很拙,等后面知识丰富点再加之改进。

int main()
{
	game();

	return 0;
}

main函数,不太喜欢再main里面写一大堆,然后就用game函数调用了。

//这里都是.h文件,声明都在这里进行
//一些注意的点我会加之标记
void game();
void menu();//打印菜单函数
void chushihua(struct uct* p1);
//见名知意,初始化函数把结构体内容置空
void addformation(struct uct* p1);
//添加成员信息
void showformation(struct uct* p1);
//显示成员信息
void subformation(struct uct* p1);
//删除成员信息
void searchformation(const struct uct* p1);
//查找成员信息
void modifyformation(struct uct* p1);
//对成员排序
int cmp_stu_name(const void* p1, const void* p2);
//自己实现的结构体比较方法

//枚举类型,第一个为0,配合后面的switch case 语句使用。
enum arr
{
	EXIT,
	ADD,
	SUB,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
//这是结构体成员信息
struct information
{
	char name[MAX_NAME];
	int age;
	char set[MAX_SAT];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
};
//上一个结构体变量定义在这个结构体里面了,
//同时还要给一个数组,为了后面方便接受信息就这样定义了两个结构体
struct uct
{
	struct information data[MAX];
	int size;
};

//打印菜单函数
void menu()
{
	printf("*******************************\n");
	printf("*****1 add           2 sub*****\n");
	printf("*****3 search        4 modify*****\n");
	printf("*****5 show          6 sort****\n");
	printf("*********   0 exit    *********\n");
	printf("*******************************\n");
}
//初始化
void chushihua(struct uct* p1)
{
	memset(p1->data, 0, sizeof(p1->data));
	//这里的data是数组首元素,在sizeof()里面代表的是整个数组
	p1->size = 0;
}
//添加成员信息
//使用结构体指针更方便也节省空间
void addformation(struct uct* p1)
{
	if (p1->size == MAX)//判断是否超出范围
	{
		printf(" 存储已满 !\n");
	}
	else
	{
		printf("请添加信息\n");
		printf("请输入名字 -> \n");
		scanf("%s", p1 ->data[p1->size].name);
		printf("请输入年龄 -> \n");
		scanf("%d",&(p1 ->data[p1->size].age));
		printf("请输入性别 -> \n");
		scanf("%s", p1 ->data[p1->size].set);
		printf("请输入电话 -> \n");
		scanf("%s", p1 ->data[p1->size].tele);
		printf("请输入地址 -> \n");
		scanf("%s", p1 ->data[p1->size].addr);
		printf(" 添加成功 !\n");
		p1->size++;
		//添加几个成员信息size就是几
	}
}
//显示成员信息
//这个是从第0个开始往后打印
//打印到size个就停止
void showformation(struct uct* p1)
{
	int i = 0;
	if (p1->size == 0)
	{
		printf("内容为空\n");
	}
	else
	{
		printf("%-16s\t%-3s\t%-6s\t%-12s\t%-15s\n","姓名","年龄","性别","电话","地址");
		for (i = 0; i < p1->size; ++i)
		{
			printf("%-16s\t%-3d\t%-5s\t%-12s\t%-15s\n", p1->data[i].name,
			 p1->data[i].age,
			 p1->data[i].set,
			 p1->data[i].tele,
			 p1->data[i].addr);
		}
	}
}
//因为这个查找 改 和 删 都要用到
//所以就使用static修饰,同时独立实现查找功能
//减少代码冗余
static int sertch(const struct uct* p1,char name[MAX_NAME])
{
	int i = 0;
	for (i = 0; i < p1->size; ++i)
	{
		if (0 == strcmp(p1->data[i].name, name))
			return i;
	}
	return -1;
}
//删除联系人
void subformation(struct uct* p1)
{
	char name[MAX_NAME];
	printf("请输入要删除人的名字");
	scanf("%s", name);
	int ret = sertch(p1,name);
	if (ret == -1)
	//上面的如果没有找到就会返回-1,跟这个配合上
		printf("该联系人不存在!\n\n");
	else
	{
	//用的还是土方法,删除哪一个就从下一个信息一个个往前挪
		while (ret < p1->size - 1)
		{
			p1->data[ret] = p1->data[ret + 1];
			++ret;
		}
		p1->size--;
		printf("删除成功!\n\n");
	}
}
//查找函数
//因为只负责查找可以使用const修饰,防止被改变
void searchformation(const struct uct* p1)
{
	char name[MAX_NAME];
	printf("请输入你要查找人的姓名:");
	scanf("%s", name);
	int i = sertch(p1, name);
	if (i == -1)
		printf("未查找到该联系人\n");
	else
	{
		printf("%-16s\t %-3s\t %-6s\t %-12s\t %-15s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-16s\t%-3d\t%-5s\t%-12s\t%-15s\n", p1->data[i].name,
			p1->data[i].age,
			p1->data[i].set,
			p1->data[i].tele,
			p1->data[i].addr);
	}
}
//修改信息函数
void modifyformation(struct uct* p1)
{
	char name[MAX_NAME];
	printf("请输入要修改人的信息:");
	scanf("%s", name);
	int ret = sertch(p1, name);
	if (ret == -1)
	{
		printf("未找到该联系人\n");
	}
	else
	{
		printf("请添加信息\n");
		printf("请输入名字 -> \n");
		scanf("%s", p1->data[ret].name);
		printf("请输入年龄 -> \n");
		scanf("%d", &(p1->data[ret].age));
		printf("请输入性别 -> \n");
		scanf("%s", p1->data[ret].set);
		printf("请输入电话 -> \n");
		scanf("%s", p1->data[ret].tele);
		printf("请输入地址 -> \n");
		scanf("%s", p1->data[ret].addr);
		printf(" 修改 成功 !\n");
	}
}
//这个是结构体里面的字符串比较函数
//这个函数不熟的话会有点坑
//它会被qsort函数调用很多次,所以你一句一句代码运行的时候
//它会运行很多次,因为要判断很多次,所以会给你一种卡在return走不动的假象
//有点坑,新手还是要多研究研究这个函数
//尽量要发散思维想的更全面一些
int cmp_stu_name(const void* p1,const void* p2)
{
	//return strcmp(((struct information*)p1)->name, ((struct information*)p2)->name);
	return strcmp(((struct information*)p1)->name,((struct information*)p2)->name);
}
//这就是main函数里面调用的实现功能函数了
//各种函数都在这里调用
void game()
{
	int input = 0;
	struct uct s1;
	chushihua(&s1);
	do
	{
		menu();
		printf("\n");
		printf("\n");
		printf("please input a number:");
		scanf_s("%d", &input);
		//输入input  p配合后面的switch语句
		int sz = s1.size;
		//每次求这个数组元素个数的时候
		//本能反应直接sizeof(数组名)/sizeof(数组首元素[0]),唉咋说呢,还是要细心
		//qsort排序可以直接输入你要排序的数组元素个数
		//其实不需要传整个数组所有的元素
		//然后因为这个还要再想办法怎么只打印有信息的
		//很简单的一个地方但是有时候就是没有反应过来
		//代码出bug的时候一步步调试,找不到问题就放一放,睡一觉起来说不定就有思路了呢
		switch (input)
		{
		//里面配合枚举使用
		//exit是0 add是1,等等
		case ADD:
			addformation(&s1);
			break;
		case SUB:
			subformation(&s1);
			break;
		case SEARCH:
			searchformation(&s1);
			break;
		case MODIFY:
			modifyformation(&s1);
			break;
		case SHOW:
			showformation(&s1);
			break;
		case SORT:
		//库函数,快速排序
			qsort(s1.data, sz, sizeof(s1.data[0]),cmp_stu_name);
			break;
		case EXIT:
				printf("退出 \n");
				break;
		default :
				printf("输入错误!\n");
				break;
		}

	} while (input);//输入零循环判断为假退出循环
}

结束
开心的一天来自解决问题,感觉整个人都轻松了,今天晚上心血来潮写了一遍扫雷,还差最后一个功能,那个递归一下一大片的还得好好想想
明天做好分享出来吧,有些坑的地方会做标记
还是要细心。
得马上十点半了,得赶快睡觉,年轻人身体重要😌

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值