C语言实现基础通讯录系统(静态存储)

前言:

老师两节课写出来的东西,我却花了两天时间,而且是在翻资料和借助人工智能辅助的前提下完成的。

黑发不知勤学早啊!!!!!!

大一不好好学,基础打不好,实训也白做。现在是听课学习的前提下,非常非常勉强地实现了基本功能,尽管这个系统很low,还有许多要完善的地方和功能,但不是我这个水平足以评价的。

错误/问题点:

超级多超级多!!!!全标在代码旁边

很多地方都是下意识去“背代码”,而不是掌握用法,导致照猫画虎,改了前面不会改后面。

头文件

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<memory.h>
#include<string.h>

#define max_name 12
#define max_sex 10
#define max_address 30
#define max_person 10000

//信息包含的内容
typedef struct message_content//漏掉typedef,导致main.c中struct无法省略
{
	char name[max_name];
	char sex[max_sex];
	int age;
	int tele;
	char address[max_address];
}content;

//通讯录
typedef struct person_message
{
	content all_data[max_person];//通讯录总容量
	int available_data;//可用信息的个数
}message;


//函数声明(写在message上面且无struct的话会报错)
void init_message(message* mess);
void add_message(message* mess);
void print_message(const message* mess);//根本没想到要固定mess
void delete_message(message* mess);
void search_message(message* mess);
int find_all_names(message* mess, char name[], int ret[]);//没考虑到删除、修改、查询都要用到“查找”指令
void modify_message(message* mess);
void sort_message(message* mess);
void sort_menu();
void sort1(message* mess);
void sort2(message* mess);

主函数

#include"address_book.h"

void menu()
{
	printf("\n  ********************************************\n");
	printf("  ********************************************\n");
	printf("  ******    通   讯   录   系   统     *******\n");
	printf("  ******    0.退出系统     1.增加信息  *******\n");
	printf("  ******    2.删除信息     3.查找信息  *******\n");
	printf("  ******    4.修改信息     5.排序信息  *******\n");
	printf("  ******    6.打印信息                 *******\n");
	printf("  ********************************************\n");
	printf("  ********************************************\n");
}

enum option
{
	EXIT,
	ADD,
	DELETE,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};
int main()
{
	//创建通讯录
	message mess;
	//初始化通讯录(&mess不是mess或 * mess;传地址而不是传值)
	init_message(&mess);
	int input = 0;
	do
	{
		menu();
		printf("请输入你的选择: ");
		scanf("%d",&input);
		switch (input)
		{
		case EXIT:
			printf("退出系统!\n");
			break;
		case ADD:
			printf("增加信息:\n");
			add_message(&mess);
			break;
		case DELETE:
			printf("删除信息:\n");
			delete_message(&mess);
			break;
		case SEARCH:
			printf("查找信息:\n");
			search_message(&mess);
			break;
		case MODIFY:
			printf("修改信息:\n");
			modify_message(&mess);
			break;
		case SORT:
			printf("排序信息:\n");
			sort_message(&mess);
			break;
		case PRINT:
			printf("打印信息:\n");
			print_message(&mess);
			break;
		default:
			printf("无该选项,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

通讯录实现

#include"address_book.h"

//初始化通讯录信息
void init_message(message* mess)
{
	mess->available_data = 0;
	memset(mess->all_data, 0, sizeof(mess->all_data));//memset内存设置(初始化可全0或非全0)
}

void add_message(message* mess)
{
	if (mess->available_data == max_person)
	{
		printf("通讯录可用信息容量已满,无法添加新信息!\n");
		return;//结束执行,但不用返回值
	}
	else
	{
		// mess->all_data[mess->available_data]:将可用空间的信息放进总容量对应下标的空间
		// 把第n个添加进来的信息放在总数据中下标为n的位置
		// available=1 ==》all_data=1
		// 例:第0个学生放在下标为0的all_data中
		printf("请输入姓名:");
		scanf("%s", mess->all_data[mess->available_data].name);
		printf("请输入性别:");
		scanf("%s", mess->all_data[mess->available_data].sex);//无法读取性别原因:scanf中加了"\n"!!!!!!
		//int i=0;scanf("%d",&i);
		//要取地址
		printf("请输入年龄:");
		scanf("%d", &(mess->all_data[mess->available_data].age));
		printf("请输入联系方式:");
		scanf("%d",&(mess->all_data[mess->available_data].tele));
		printf("请输入住址:");
		scanf("%s", mess->all_data[mess->available_data].address);
		mess->available_data++;//已用空间+1
		printf("输入信息成功!\n");
	}
}

void print_message(const message* mess)//根本没想到要固定mess
{
	//打印标题(-左对齐)
	printf("%-8s\t%-8s\t%-8s\t%-20s\t%-20s\n", "姓名", "性别", "年龄", "联系方式", "住址");
	//打印内容
	int i = 0;
	for ( i = 0; i < mess->available_data; i++)
	{
		printf("%-8s\t%-8s\t%-8d\t%-20d\t%-20s\n",//忘记把 "年龄", "联系方式"改为“%d”
			mess->all_data[i].name,//没有考虑到【i】,而是写成all_data.name
			mess->all_data[i].sex,
			mess->all_data[i].age,
			mess->all_data[i].tele,
			mess->all_data[i].address);
	}
}
//static:只能在本源文件用,不能被其他源文件使用
//又是一个想不到的地方
static int find_all_names(message* mess, char name[], int ret[])
{
	int i = 0;
	int j = 0;
	for (i = 0; i < mess->available_data; i++)
	{
		//两个字符串不能直接用等号!!!!!
		if (strcmp(name, mess->all_data[i].name) == 0)
		{
			ret[j] = i;//将所有名字相同的下标存储到一个数组里
			j++;//记录存储在ret数组中的索引数量
		}
	}
	return j;
}

void delete_message(message* mess)
{
	//判断
	if (mess->available_data == 0)
	{
		printf("通讯录为空!无法删除!\n");
		return;
	}
	int ret[max_person] = { 0 };//将所有名字相同的下标存储到一个数组里
	char name[max_name] = { 0 };//写成int类型(无语)
	printf("请输入你要删除的(信息)名字:");
	//int改成char之后,%d没改成%s,导致无论输什么,都提示信息不存在!!!!
	scanf("%s", name);
	int count = find_all_names(mess, name, ret);//没考虑到删除、修改、查询都要用到“查找”指令
	if (count == 0)
	{
		printf("你输入的信息不存在!无法删除!\n");
		return;
	}
	//执行
	int i = 0;
	//count:相同名字的数量,for条件要么写成count-1,i>0;要么写成count,i>=0,导致怎么删除都不对!!!
	for (i = count - 1; i >= 0; i--)
	{
		int index = ret[i];//想不到!根本想不到!!!!
		while (index < mess->available_data - 1)
		{
			//available_data - 1,count - 1原因:最后一个数字替换之后,还会出现最后一个数字下标+1的数,栈溢出
			//例:1 2 3 4 5,把1删除后,2覆盖到1的位置,3覆盖2位置,4覆盖3,5覆盖4,如果不减一,会出现5后面的空值覆盖5的情况
			mess->all_data[index] = mess->all_data[index + 1];
			index++;
		}
		mess->available_data--; //--写成++,导致无论怎么删,打印依旧还存在
	}
	printf("删除成功!\n");
}

void search_message(message* mess)
{
	char name[max_name] = { 0 };
	while (1)
	{
		printf("请输入你要查找的名字:");
		scanf("%s", name);
		int ret[max_person] = { 0 };//想不到,根本想不到!!!!!!
		int count = find_all_names(mess, name, ret);
		if (count == 0)
		{
			printf("你输入的信息不存在!无法查找!\n");
			return;
		}
		else
		{
			printf("已找到信息!\n");
			printf("%-8s\t%-8s\t%-8s\t%-20s\t%-20s\n", "姓名", "性别", "年龄", "联系方式", "住址");
			int i = 0;
			for (i = 0; i < count; i++)
			{
				printf("%-8s\t%-8s\t%-8d\t%-20d\t%-20s\n",
					mess->all_data[ret[i]].name,//ret[i]:将所有名字相同的下标存储到一个数组里
					mess->all_data[ret[i]].sex,
					mess->all_data[ret[i]].age,
					mess->all_data[ret[i]].tele,
					mess->all_data[ret[i]].address);
			}
			break;
		}
	}
}

void modify_message(message* mess)
{
	char name[max_name] = { 0 };
	printf("请输入你要修改的数据姓名:");
	scanf("%s", name);
	int ret[max_person] = { 0 };//想不到,根本想不到!!!!!!
	int count = find_all_names(mess, name, ret);
	int i = 0;
	if (count == 0)
	{
		printf("你输入的信息不存在!无法修改!\n");
		return;
	}
	for (i = 0; i < count; i++) 
	{
		char choice = 0;
		printf("找到第%d个匹配的人,名字是%s。确定修改信息吗(y/n)? 或者继续输入名字:%s 进行查询?\n", i + 1, mess->all_data[ret[i]].name, mess->all_data[ret[i]].name);
		scanf(" %c", &choice); //注意空格,它可以消除缓冲区中的任何空白字符(想不到!根本想不到!!!!)
		if (choice == 'y' || choice == 'Y') 
		{
			printf("请输入姓名:");
			scanf("%s", mess->all_data[ret[i]].name);// ret[i]:将所有名字相同的下标存储到一个数组里
			printf("请输入性别:");
			scanf("%s", mess->all_data[ret[i]].sex);
			printf("请输入年龄:");
			scanf("%d", &(mess->all_data[ret[i]].age));
			printf("请输入联系方式:");
			scanf("%d", &(mess->all_data[ret[i]].tele));
			printf("请输入住址:");
			scanf("%s", mess->all_data[ret[i]].address);
			printf("修改信息成功!\n");
			break;
		}
	}
	if (i == count)
	{
		printf("共%d个数据,已查询完毕,请重新选择!\n",count);
	}
}

void sort_menu()
{
	printf("*********************\n");
	printf("******* 1.正序 ******\n");
	printf("******* 2.倒序 ******\n");
	printf("*********************\n");
}
void sort1(message* mess)
{
	int i = 0;
	int j = 0;
	int temp_age = 0;
	int temp_tele = 0;
	char temp_name[max_name] = { 0 };
	char temp_sex[max_sex] = { 0 };
	char temp_address[max_address] = { 0 };
	for ( i = 0; i < mess->available_data - 1; i++)
	{
		for ( j = 0; j < mess->available_data - 1 - i; j++)
		{
			if (mess->all_data[j].age > mess->all_data[j + 1].age)
			{
				temp_age = mess->all_data[j].age;//没把name改为age,导致报错
				mess->all_data[j].age = mess->all_data[j + 1].age;
				mess->all_data[j + 1].age = temp_age;

				temp_tele = mess->all_data[j].tele;//没把name改为age,导致报错
				mess->all_data[j].tele = mess->all_data[j + 1].tele;
				mess->all_data[j + 1].tele = temp_tele;

				strcpy(temp_name, mess->all_data[j].name);//不交换name,就显示只交换了年龄,其他信息未排序
				strcpy(mess->all_data[j].name, mess->all_data[j + 1].name);
				strcpy(mess->all_data[j + 1].name, temp_name);

				strcpy(temp_sex, mess->all_data[j].sex);
				strcpy(mess->all_data[j].sex, mess->all_data[j + 1].sex);
				strcpy(mess->all_data[j + 1].sex, temp_sex);

				strcpy(temp_address, mess->all_data[j].address);
				strcpy(mess->all_data[j].address, mess->all_data[j + 1].address);
				strcpy(mess->all_data[j + 1].address, temp_address);
			}
		}
	}
	printf("%-8s\t%-8s\t%-8s\t%-20s\t%-20s\n", "姓名", "性别", "年龄", "联系方式", "住址");
	for (j = 0; j < mess->available_data; j++)
	{
		printf("%-8s\t%-8s\t%-8d\t%-20d\t%-20s\n",
			mess->all_data[j].name,
			mess->all_data[j].sex,
			mess->all_data[j].age,
			mess->all_data[j].tele,
			mess->all_data[j].address);
	}
}
void sort2(message* mess)
{
	int i = 0;
	int j = 0;
	int temp_age = 0;
	int temp_tele = 0;
	char temp_name[max_name] = { 0 };
	char temp_sex[max_sex] = { 0 };
	char temp_address[max_address] = { 0 };
	for (i = 0; i < mess->available_data - 1; i++)
	{
		for (j = 0; j < mess->available_data - 1 - i; j++)
		{
			if (mess->all_data[j].age < mess->all_data[j + 1].age)
			{
				temp_age = mess->all_data[j].age;//没把name改为age,导致报错
				mess->all_data[j].age = mess->all_data[j + 1].age;
				mess->all_data[j + 1].age = temp_age;

				temp_tele = mess->all_data[j].tele;//没把name改为age,导致报错
				mess->all_data[j].tele = mess->all_data[j + 1].tele;
				mess->all_data[j + 1].tele = temp_tele;

				strcpy(temp_name, mess->all_data[j].name);//不交换name,就显示只交换了年龄,其他信息未排序
				strcpy(mess->all_data[j].name, mess->all_data[j + 1].name);
				strcpy(mess->all_data[j + 1].name, temp_name);

				strcpy(temp_sex, mess->all_data[j].sex);
				strcpy(mess->all_data[j].sex, mess->all_data[j + 1].sex);
				strcpy(mess->all_data[j + 1].sex, temp_sex);

				strcpy(temp_address, mess->all_data[j].address);
				strcpy(mess->all_data[j].address, mess->all_data[j + 1].address);
				strcpy(mess->all_data[j + 1].address, temp_address);
			}
		}
	}
	printf("%-8s\t%-8s\t%-8s\t%-20s\t%-20s\n", "姓名", "性别", "年龄", "联系方式", "住址");
	for (j = 0; j < mess->available_data; j++)
	{
		printf("%-8s\t%-8s\t%-8d\t%-20d\t%-20s\n",
			mess->all_data[j].name,
			mess->all_data[j].sex,
			mess->all_data[j].age,
			mess->all_data[j].tele,
			mess->all_data[j].address);
	}
}
void sort_message(message* mess)
{
	int i = 0;
	sort_menu();
	printf("请输入你要排序的方式(年龄):");
	scanf("%d", &i);
	switch (i)
	{
	case 1:
		sort1(mess);//woc!!!!!!!!这里是传mess,而不是&mess,否则始终无法输出数据
		break;
	case 2:
		sort2(mess);
		break;
	default:
		break;
	}
}
//mess已经是一个指针,它存储了message结构体的地址。当你使用&mess时,你其实是在获取这个指针变量自身的地址,而不是它所指向的message结构体。
// 因此,在这种情况下,你应该直接传递mess(即地址),而不是&mess。
// 这样,sort1函数就能正确地接收到一个指向message结构体的指针,并能够操作这个结构体。
//总的来说,选择传值还是传地址取决于你是否需要在函数内部修改实参。
//如果需要修改实参,那么应该使用传地址;如果不需要修改实参或者不希望实参被修改,那么应该使用传值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言课程设计任务书(4) 一、题目:通讯录管理 二、目的与要求 1. 目的: (1)基本掌握面向过程程序设计的基本思路和方法; (2)达到熟练掌握C语言的基本知识和技能; (3)能够利用所学的基本知识和技能,解决简单的程序设计问题 2. 要求 基本要求: 1.         要求利用C语言面向过程的编程思想来完成系统的设计; 2.       突出C语言的函数特征,以多个函数实现每一个子功能; 3.         画出功能模块图; 4.         具有清晰的程序流程图和数据结构的详细定义; 5.       熟练掌握C语言对文件的各种操作。 创新要求: 在基本要求达到后,可进行创新设计,如系统用户功能控制,对管理员级和一般级别的用户系统功能操作不同 三、信息描述 有关该系统基本信息的描述,如:姓名、电话、城市和邮编等。 四、功能描述 1.       名单基本信息(姓名,城市,电话,邮编等)的录入,并存放在文件当中。 2.       基本信息的查询与修改。 3.       记录的添加和删除。 4.       对同一类型记录的查找:如查找同一城市的记录或同一省份的记录。 五、解决方案 1.       分析程序的功能要求,划分程序功能模块。 2.       画出系统流程图。 3.       代码的编写。定义数据结构和各个功能子函数。 4.       程序的功能调试。 5.       完成系统总结报告以及使用说明书 六、进度安排 此次课程设计时间为一周或两周,分四个阶段完成: 1.       分析设计阶段。指导教师应积极引导学生自主学习和钻研问题,明确设计要求,找出实现方法,按照需求分析、总体设计、详细设计这几个步骤进行。 2.       编码调试阶段:根据设计分析方案编写C代码,然后调试该代码,实现课题要求的功能。 3.       总结报告阶段:总结设计工作,写出课程设计说明书,要求学生写出需求分析、总体设计、详细设计、编码、测试的步骤和内容。 4.       考核阶段。 七、撰写课程设计报告或课程设计总结 课程设计报告要求: 总结报告包括需求分析、总体设计、详细设计、编码(详细写出编程步骤)、测试的步骤和内容、课程设计总结、参考资料等,不符合以上要求者,则本次设计以不及格记。 八、参考资料  《C语言程序设计教程》   网上相关资料(....略)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值