姓名册项目

创建一个姓名册

1.定义节点

首先需要知道,如果想要创建一个姓名册项目,如何定义一个姓名册的节点,节点当中需要含有些什么属性。
对于一个姓名册来说,一个节点至少需要包括一条姓名册所需的信息,本项目采用链表来存储所有的姓名信息,因为使用链表存储可以快速的查询到所用的信息。
定义节点结构体:

typedef struct NODE
{
	int id;
	char *name;
	char *tel_num;
	struct NODE *p_next;
}Node;

2.首先创建姓名册的节点

即首先创建姓名信息,如-----ID:1,Name:Abcde,TELEPHONE:18856231111

Node* CreateNode()
{
	Node *p_node = (Node*)malloc(sizeof(Node));
	p_node->id = AutoID;
	p_node->name = AutoName;
	p_node->tel_num = AutoTelNum;
	p_node->p_next = NULL;
	
	return p_node;
}

3.创建101个姓名信息

使用链表将其连接起来。

void AppendNode(Node **pp_head, Node **pp_end, Node *p_node)
{
	if(*pp_head)
	{
		*pp_end->p_next = p_node;
	}
	else
	{
		*pp_head = p_node;
	}
	*pp_end = p_node;
	
	return;
}

4.检测是否可以进行创建姓名册信息

生成空Node指针头和指针尾,用来记录姓名册。


#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "string.h"
#include <string.h>


typedef struct NODE
{
	int id;
	char *name;
	char *tel_num;
	struct NODE *p_next;
}Node;

typedef struct PAGE
{
	int total_info_num;   //数据的总数目
	int info_peer_page;   //每页有多少数据
	int current_page;		//当前页的页码
	int total_page;			//总页数
}Page;


int g_menu_flag;
char g_out_or_not;


//功能函数
Node* CreateNode();
void AppendNode(Node **pp_head, Node **pp_end, Node *node);
int AutoId();
char* AutoName();
char* AutoTelNum();
Page* GetPageInfo(Node *p_head, int info_peer_page);
void ShowOnePage(Node *p_head, Page *page);
void ShowPageInfo(Page *page);
void TurnPage(Node *p_head, Page *page);
//10.31日从此处开始
char GetKey();
void Browse(Node *p_head);
void ShowMenu(Node **p_head, Node **p_end);
Node* CreateInputNode();
char *GetString();
// 11.1日从从此处开始
void QueryInfo(Node *p_head);
// 11.2日从此处开始
void DeleteOneNode(Node **pp_head, Node **pp_end, int id);
void DeleteInfo(Node **pp_head, Node **pp_end);
void ChangeInfo(Node *p_head);
void ChangeOneInfoName(Node *p_head, int id, char *p_name);
void ChangeOneInfoTelNum(Node *p_head, int id, char *tel_num);




//测试用函数
void InitialInformation(Node **pp_head, Node **pp_end, int num_init_info);
void PrintInformation(Node **pp_head);





int main()
{
	Node *p_head = NULL;
	Node *p_end = NULL;
	Page *page_info = NULL;

	//测试数据
	InitialInformation(&p_head, &p_end, 101);

	//Browse(p_head);
	ShowMenu(&p_head, &p_end);





	return 0;
}

// """创建一个新节点"""
Node* CreateNode()
{
	//手动申请一个存放节点的空间
	Node *node = (Node*)malloc(sizeof(Node));
	node->id = AutoId();
	node->name = AutoName();//"Aaaa";
	node->tel_num = AutoTelNum();
	node->p_next = NULL;

	return node;
}

void AppendNode(Node **pp_head, Node **pp_end, Node *node)
{
	//在末尾添加节点
	if(*pp_head == NULL)
	{
		*pp_head = node;
	}
	else
	{
		(*pp_end)->p_next = node;
	}
	*pp_end = node;

	return;
}

int AutoId()
{
	//生成自动增加的ID编号
	static int id = 0;

	return ++id;
}

char* AutoName()
{
	//生成自动生成的名字
	char *name = (char*)malloc(sizeof(char) * 6);
	int count;
	name[0] = 65 + rand()%26;
	for(count=1; count<5; count++)
	{
		name[count] = 97 + rand()%26;
	}
	name[count] = '\0';

	return name;
}

char* AutoTelNum()
{
	//自动生成电话号码
	char *tel_num = (char*)malloc(sizeof(char) * 12);
	int count;

	switch (rand() % 4)
	{
	case 0:
		strcpy_s(tel_num, 12, "131");
		break;
	case 1:
		strcpy_s(tel_num, 12, "155");
		break;
	case 2:
		strcpy_s(tel_num, 12, "186");
		break;
	case 3:
		strcpy_s(tel_num, 12, "188");
		break;
	}

	for(count=3; count<11; count++)
	{
		tel_num[count] = (rand()%10) + '0';
	}
	tel_num[count] = '\0';

	return tel_num;
}

Page* GetPageInfo(Node *p_head, int info_peer_page)
{
	//生成一个页表信息
	Page *page_point = (Page*)malloc(sizeof(Page));
	page_point->current_page = 0;
	page_point->info_peer_page = info_peer_page;
	page_point->total_info_num = 0;

	while(p_head)
	{
		page_point->total_info_num++;
		p_head = p_head->p_next;
	}

	//三目运算符
	page_point->total_page = page_point->total_info_num % page_point->info_peer_page == 0 
		? page_point->total_info_num / page_point->info_peer_page 
		: page_point->total_info_num / page_point->info_peer_page + 1;

	return page_point;
}

void ShowOnePage(Node *p_head, Page *page)
{
	//显示一页的信息,
	int begin_page = page->current_page * page->info_peer_page - page->info_peer_page + 1;
	int end_page = page->current_page * page->info_peer_page;
	int count_flag = 0;

	while (p_head)
	{
		count_flag++;
		if(count_flag >= begin_page && count_flag <= end_page)
		{
			printf("ID:%-5d\tName:%-10s\tTelphone Number:%-11s\n", p_head->id, p_head->name, p_head->tel_num);
		}
		p_head = p_head->p_next;
	}

	return;
}

void ShowPageInfo(Page *page)
{
	//显示页面信息:共有多少页、共有多少条、当前页数
	// 查询信息与查看信息使用的不是同一个菜单,因此设置全局变量来标记是 查询信息还是查看信息
	if(1 == g_menu_flag)
	{	
		printf("**************************************************************\n");
		printf("Current Page:%d \tTotal Page:%d\tTotal Information:%d\tw:last page\ts:next page\tq:exit\n", 
			page->current_page, page->total_page, page->total_info_num);
	}
	if(3 == g_menu_flag)
	{
		printf("**************************************************************\n");
		printf("Current Page:%d \tTotal Page:%d\tTotal Information:%d\tw:last page\ts:next page\tc:Query Again\tq:exit\n", 
			page->current_page, page->total_page, page->total_info_num);
	}
	if(4 == g_menu_flag)
	{
		printf("**************************************************************\n");
		printf("Current Page:%d \tTotal Page:%d\tTotal Information:%d\tw:last page\ts:next page\td:Delete Infomation\tq:exit\n", 
			page->current_page, page->total_page, page->total_info_num);
	}
	if(5 == g_menu_flag)
	{
		printf("**************************************************************\n");
		printf("Current Page:%d \tTotal Page:%d\tTotal Information:%d\tw:last page\ts:next page\tg:Change Infomation\tq:exit\n", 
			page->current_page, page->total_page, page->total_info_num);
	}
	return;
}

void TurnPage(Node *p_head, Page *page)
{
	//用来进行翻页操作
	char c = 's';

	while(1)
	{
		switch(c)
		{
		case 's':
			if(page->current_page >= page->total_page)
			{
				printf("已经是最后一页了\n");
			}
			else
			{
				page->current_page++;
				ShowOnePage(p_head,page);
				ShowPageInfo(page);
			}
			break;
		case 'w':
			if(page->current_page <= 1)
			{
				printf("已经是第一页了\n");
			}
			else
			{
				page->current_page--;
				ShowOnePage(p_head,page);
				ShowPageInfo(page);
			}			
			break;
		case 'c':
			if(g_menu_flag == 1)
				printf("按错了\n");
			if(g_menu_flag == 3)
				return;
			break;
		case 'd':
			// 删除信息
			if(g_menu_flag == 1)
				printf("按错了\n");
			if(g_menu_flag == 4)
				return;
			break;
		case 'g':
			// 修改信息
			if(g_menu_flag == 1)
				printf("按错了\n");
			if(g_menu_flag == 5)
				return;
			break;
		case 'q':
			return;
			break;
		default:
			printf("按错了\n");
			break;
		}

		c = GetKey();
		g_out_or_not = c;
	}

	return;
}

char GetKey()
{
	// 用来进行消除 '\n' 字符
	// 需要改进,本次只能消除一次之前的非法符号
	// 需要改进
	char temp1;
	char temp2;
	int flag = 1;
	while ((temp1 = getchar()) != '\n' || flag)
	{
		temp2 = temp1;
		flag = 0;
	}

	return temp2;
}

void Browse(Node *p_head)
{
	// 将生成页面信息与翻页操作封装为一个函数,即将 GetPage与TurnPage 封装为一个函数
	Page *page_info = GetPageInfo( p_head,10);
	TurnPage(p_head, page_info);
}

void ShowMenu(Node **p_head, Node **p_end)
{
	// 显示菜单操作函数
	char c;
	while(1)
	{
		printf("1.查看信息\n");
		printf("2.添加信息\n");
		printf("3.查询信息\n");
		printf("4.删除信息\n");
		printf("5.修改信息\n");
		printf("Q.退出\n");
		c = GetKey();
		switch (c)
		{
		case '1':
			g_menu_flag = 1;
			Browse(*p_head);
			break;
		case '2':
			AppendNode(p_head, p_end, CreateInputNode());
			break;
		case '3':
			g_menu_flag = 3;
			QueryInfo(*p_head);
			break;
		case '4':
			g_menu_flag = 4;
			DeleteInfo(p_head, p_end);
			break;
		case '5':
			g_menu_flag = 5;
			ChangeInfo(*p_head);
			break;
		case 'q':
			return;
			break;
		default:
			break;
		}
	}
	return;
}

Node* CreateInputNode()
{
	Node *node = (Node*)malloc(sizeof(Node));
	node->id = AutoId();
	printf("Please Input Name:");
	node->name = GetString();
	printf("Please Input Telephone Number:");
	node->tel_num = GetString();
	node->p_next = NULL;

	return node;
}

char* GetString()
{
	int str_size = 5;
	char *old_str = (char*)malloc(str_size);
	char *new_str = NULL;
	int count = 0;
	char *p_old = old_str;
	char char_temp;

	while ((char_temp = getchar()) != '\n')
	{
		*old_str = char_temp;
		old_str++;
		count++;
		if(count + 1 == str_size)
		{
			*old_str = '\0';
			str_size += 5;
			new_str = (char*)malloc(str_size);
			strcpy_s(new_str, str_size, p_old);
			old_str = new_str + count;
			free(p_old);
			p_old = new_str;
		}
	}

	*old_str = '\0';

	return p_old;
}

void QueryInfo(Node *p_head)
{
	// 查询信息,输入为名字或电话号,支持模糊查询
	Node *new_p_head = NULL;				// 用来存放查找到的信息
	Node *new_p_end = NULL;
	Node *temp_node = NULL;					// 用来存放某个查找到的节点
	Node *p_head_flag = p_head;				// 用来记录起始点
	Node *p_del = NULL;
	char *key_word = NULL;					// 记录输入的关键字
	int flag_of_cmp;						// 记录关键字与信息的相关性		0:完全相同

	while(1)
	{
		// 1.输入关键字,并确定关键字或重新输入关键字
		while (1)
		{
			printf("Please Input Key Word:");
			key_word = GetString();
			printf("a.确定\t按其他键重新输入");
			if('a' == GetKey())
			{
				break;
			}
			else
			{
				free(key_word);
				key_word = NULL;
				continue;
			}
		}

		// 2.进行查询操作
		p_head = p_head_flag;
		while (p_head)
		{
			// 判断关键字是否是电话号码
			if(*key_word <= '9' && *key_word >= '0')
			{
				flag_of_cmp = strncmp(p_head->tel_num, key_word, strlen(key_word));
				if(0 == flag_of_cmp)
				{
					temp_node = (Node *)malloc(sizeof(Node));
					temp_node->id = p_head->id;
					temp_node->name = p_head->name;
					temp_node->tel_num = p_head->tel_num;
					temp_node->p_next = NULL;

					AppendNode(&new_p_head, &new_p_end, temp_node);
				}
			}
			else
			{
				flag_of_cmp = strncmp(p_head->name, key_word, strlen(key_word));
				if(!flag_of_cmp)
				{
					temp_node = (Node *)malloc(sizeof(Node));
					temp_node->id = p_head->id;
					temp_node->name = p_head->name;
					temp_node->tel_num = p_head->tel_num;
					temp_node->p_next = NULL;

					AppendNode(&new_p_head, &new_p_end, temp_node);
				}
			}
			p_head = p_head->p_next;
		}

		// 显示查询的结果
		if(!new_p_head)
		{
			printf("None is avalible!\n");
		}
		else
		{
			Browse(new_p_head);
		}

		// 删除暂存的符合查找的信息
		while(new_p_head)
		{
			p_del = new_p_head;
			new_p_head = new_p_head->p_next;
			free(p_del);
			p_del = NULL;
		}
		new_p_head = NULL;
		new_p_end = NULL;

		// 跳出查找的条件
		if(g_out_or_not == 'q' || g_out_or_not == 'd' || g_out_or_not == 'g')
			break;
	}

	return;
}

void DeleteOneNode(Node **pp_head, Node **pp_end, int id)
{
	Node *p_del = *pp_head;
	Node *p_flag = NULL;
	if(p_del->id == id)
	{
		*pp_head = p_del->p_next;
		free(p_del);
		p_del = NULL;
	}
	while(p_del)
	{
		p_flag = p_del;
		p_del = p_del->p_next;
		if(p_del->id == id)
		{
			p_flag->p_next = p_del->p_next;
			free(p_del);
			p_del = NULL;
		}
		if(!p_flag->p_next)
		{
			*pp_end = p_flag;
		}
	}

	return;
}

void DeleteInfo(Node **pp_head, Node **pp_end)
{
	// 功能:删除指定的信息
	int del_id;
	char *p_del_id = NULL;
	char flag_of_delete_again = 'y';

	while ('y' == flag_of_delete_again)
	{
		QueryInfo(*pp_head);
		if(g_out_or_not == 'q')
			break;
		printf("Please Input the id of You Want to Delete:");
		p_del_id = GetString();
		del_id = atoi(p_del_id);
		free(p_del_id);
		p_del_id = NULL;
		DeleteOneNode(pp_head, pp_end, del_id);
		printf("If you Want to Delete Another Infomation? Y/N\n");
		flag_of_delete_again = GetKey();
	}

	return;
}

void ChangeInfo(Node *p_head)
{
	// 修改信息
	int change_id;
	char *p_change_id = NULL;
	char flag_change_name_or_tel;
	char flag_change_another = 'y';
	char *p_change_name = NULL;
	char *p_change_tel = NULL;

	while ('y' == flag_change_another)
	{
		QueryInfo(p_head);
		if(g_out_or_not == 'q')
			break;
		printf("Please Input the ID that You Want to Change:");
		p_change_id = GetString();
		change_id = atoi(p_change_id);
		free(p_change_id);
		p_change_id = NULL;
		printf("Please Input What You Want to Change:\t");
		printf("For 1 means Change Name, 2 means Change Telephone Number\n");
		switch (flag_change_name_or_tel = GetKey())
		{
		case '1':
			p_change_name = GetString();
			ChangeOneInfoName(p_head, change_id, p_change_name);
			break;
		case '2':
			p_change_tel = GetString();
			ChangeOneInfoTelNum(p_head, change_id, p_change_tel);
			break;
		default:
			printf("ERROR INPUT!\n");
			break;
		}

		printf("Change Another Information? Y/N\n");
		flag_change_another = GetKey();
	}

	return;
}

void ChangeOneInfoName(Node *p_head, int id, char *p_name)
{
	while(p_head->id != id)
	{
		p_head = p_head->p_next;
	}
	free(p_head->name);
	p_head->name = p_name;

	return;
}

void ChangeOneInfoTelNum(Node *p_head, int id, char *tel_num)
{
	while(p_head->id != id)
	{
		p_head = p_head->p_next;
	}
	free(p_head->tel_num);
	p_head->tel_num = tel_num;

	return;
}



// 初始化101个节点
void InitialInformation(Node **pp_head, Node **pp_end, int num_init_info)
{
	int count;

	//埋随机数种子
	srand((unsigned int)time(NULL));

	//生成100个节点
	for(count=0; count<num_init_info; count++)
	{
		AppendNode(pp_head, pp_end, CreateNode());
	}
	return;
}

// """打印测试数据信息"""
void PrintInformation(Node **pp_head)
{
	//打印测试的数据

	//显示100个节点
	while(*pp_head != NULL)
	{
		printf("ID:%-5d\tName:%-10s\tTelphone Number:%-11s\n", (*pp_head)->id, (*pp_head)->name, (*pp_head)->tel_num);
		*pp_head = (*pp_head)->p_next;
	}

	return;
}

猜你喜欢

转载自blog.csdn.net/weixin_42896619/article/details/84105611