创建一个姓名册
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;
}