基于角色管理的简易家谱管理系统(C++/C(几乎都是C))2020-06-16

一、课题内容和要求
(一)课题要求
家谱管理系统是查询家谱信息必不可少的一部分,利用家谱管理系统可以清楚的了解家族成员信息。该家谱管理系统是通过树来实现的。要求系统界面友好,易于操作。
(二)课题要求
a)需要设置普通用户、超级管理员不同角色,不同角色登录后的权限各不相同,普通用户可以进行查询;超级管理员有对所有成员增加、删除和修改的权限。
b)家谱中的成员的信息均应包括姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡)等,也可附加其他信息,并且存储与文本文件中。
c)查询功能。可按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息、所在辈分);按照出生日期查询成员名单。
d)按照出生日期对家谱中所有人进行排序
e)打开家谱时,提示当天生日的健在成员
f)以图形方式显示家谱
(三)其他要求
(1)变量、函数命名符合规范
(2)注释详细:每个变量都要求有注释说明用途:函数有注释说明功能,对参数、返回值也要以注释的形式说明用途;关键语句段要求有注释解释
(3)程序的层次清晰,可读性强。
(4)界面美观,交互方便。
头文件treeheader.h

#ifndef TREECO_H_
#define TREECO_H_
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <time.h>  //获取搜索时刻的时间 
#include <stdbool.h>        //布尔类型
#include <stdlib.h>  //动态分配内存
#include <string.h>  //字符串处理
#include <memory.h>#define MAX_TREE_SIZE 20  //最大父亲数量
#define LEN 20      //基本属性的长度    
#define ERROR 0  
#define OK 1
using namespace std;
typedef int Status; // 状态
typedef struct //个人信息结构体
{char name[LEN];  //姓名char bothDay[LEN]; //出生日期int getMatings;    //是否结婚char address[LEN];  //其住址int keepAlive;     //是否健在char deathDay[LEN]; //若死亡,死亡日期
}ElemType;
typedef struct CTNode  //孩子节点
{int child;   //自身的标记,数组下标struct CTNode *next;  //指针域
}ChildPtr;typedef struct   //表头结构
{int parent;  //父母的信息,数组下标ElemType data; //个人信息ChildPtr* firstchild;   //
}CTBox;typedef struct  //树结构
{CTBox nodes[MAX_TREE_SIZE];   //节点数组int r, n;                       //根的位置和节点数
}CTree;
void User_login(CTree *tree);   //用户账户密码管理
void main_menu_super(CTree *tree);  //管理员菜单
void main_menu_normal(CTree *tree);  //普通用户菜单
char get_choice_menu_super();  //超级用户菜单的选择
char get_choice_menu_normal();//普通用户菜单的选择
char get_choice_Inquire();  //查询系统的选择
char get_choice_Modify();  //修改菜单的选择
ElemType Input();//录入成员信息函数
void Init(CTree *tree);  //初始化家族谱
void show_seniority(CTree *tree, int flag);  //显示查询此人时候的辈分
Status Exist_Name(CTree *tree);  //以姓名查询是否存在此人
Status Exist_BothDay(CTree *tree);  //以出生日期判断是否存在此人
void Inquire(CTree *tree); //查询功能
void Add_Child(CTree *tree, int i);  //为数组节点增加孩子 
void Add_Parent_Init(CTree *tree, int i); //为数组节点确定父节点 
void Add_Parent_Person(CTree *tree, int i);//增加新成员时父亲节点的动态变化
Status Add_Person(CTree *tree);//增加新成员
Status Remove(CTree *tree);  //删除某人
Status Modify(CTree *tree);  //修改某人信息
Status Sort_BothDay(CTree *tree);  //对家谱里的人按照出生日期进行排序
void Destroy(CTree *tree);
void Data_write(CTree *tree);
#endif

头文件中函数实现文件:implements.cpp

#include "treeheader.h"
void User_login(CTree *tree)
{char passpord[LEN] = {"123123"};    //超级用户的密码char normalUser[LEN] = {"user_normal"};  //普通用户的账号char superUser[LEN] = {"user_super"}; //超级用户的账号char input_user[LEN];  //接收用户名输入char input_password[LEN]; //接收超级用户的密码输入printf("***********\t欢迎登陆家族管理系统\t***********\n");printf("输入您的用户名:");gets(input_user);if(!strcmp(input_user, normalUser))  // 判断此输入是否与普通用户名相同{main_menu_normal(tree);  //显示普通用户的菜单}else if(!strcmp(input_user, superUser))  //判断此输入是否与超级用户名相同{printf("请输入管理员密码:");gets(input_password);  //接收密码输入if(!strcmp(input_password,passpord))  // 判断密码是否正确{main_menu_super(tree);  //显示超级用户的菜单}else{printf("密码输入错误!程序终止!!\n");exit(-1);  //密码错误,退出程序}}
}void main_menu_super(CTree *tree)  //超级用户的菜单
{int status;  //判断选择后执行的成功与否int choice;  //根据选择而执行相关功能while((choice = get_choice_menu_super()) != 'q'){switch (choice){case 'a':Init(tree);  //调用初始化函数break;case 'b':Inquire(tree);  //调用查询功能break;case 'c':status = Add_Person(tree);  //调用增加成员函数,如果成功添加,则返回OK,反之,返回ERRORif(status){printf("添加新成员成功!\n");}break;case 'd':status = Remove(tree);  //调用删除成员函数,如果成功删除,则返回OK,反之,返回ERRORif(status){printf("删除此人操作成功!\n");}else{printf("家谱中没有不存在此人!\n");}break;case 'e':status = Modify(tree);   //调用修改成员函数,如果成功修改,则返回OK,反之,返回ERRORif(status){printf("修改此人操作成功!\n");}else{printf("家谱中没有不存在此人!\n");}break;case 'f':status = Sort_BothDay(tree);  //调用按照生日排序成员函数,如果成功排序,则返回OK,反之,返回ERRORif(status){printf("排序操作成功!\n");}else{printf("排序操作失败!\n");}break;case 'g':Destroy(tree);break;case 'h':Data_write(tree);case 'q':default:break;}}
}void main_menu_normal(CTree *tree)
{int status; //判断选择后执行的成功与否int choice;//根据选择而执行相关功能while((choice = get_choice_menu_normal()) != 'q'){switch (choice){case 'a':Init(tree); //调用初始化函数break;case 'b':Inquire(tree); //调用查询功能break;case 'c':status = Sort_BothDay(tree); //调用按照生日排序成员函数,如果成功排序,则返回OK,反之,返回ERRORif(status){printf("排序操作成功!\n");}else{printf("排序操作失败!\n");}break;case 'q':default:break;}}
}char get_choice_menu_super()
{int ch;  //定义接收输入的变量printf("\t\t欢迎使用此家族管理系统!!!\t\t\t\n");printf("*************************************\n");printf("Enter the letter of your choice:\n");printf("a.  初始化家族谱\t\tb.  查询信息\n");printf("c.  增加新成员  \t\td.  删除成员\n");printf("e.  修改成员    \t\tf.  按生日进行排序\n");printf("g.  释放内存    \t\th.  存入文本文件\n");printf("**************q.    退出程序***********\n");ch = getchar(); //接收输入while(getchar() != '\n')   //清空缓冲区{continue;}return ch;  //返回输入选项,启动相关函数调用
}char get_choice_menu_normal()
{int ch; //定义接收输入的变量printf("\t\t欢迎使用此家族管理系统!!!\t\t\t\n");printf("*************************************\n");printf("Enter the letter of your choice:\n");printf("a.  初始化家族谱\t\tb.  查询信息\n");printf("c.  按生日进行排序\t\tq.    退出程序\n");printf("************************************\n");ch = getchar(); //接收输入while(getchar() != '\n')//清空缓冲区{continue;}return ch;     //返回输入选项,启动相关函数调用
}char get_choice_Inquire()
{int ch;//定义接收输入的变量printf("欢迎使用此家族管理系统的查询系统!!!\n");printf("a.  根据姓名查询                     b.  根据生日查询\n");ch = getchar();//接收输入while(getchar() != '\n')//清空缓冲区{continue;}return ch;//返回输入选项,启动相关函数调用
}char get_choice_Modify()
{int ch;//定义接收输入的变量printf("欢迎使用此家族管理系统的修改系统!!!\n");printf("a.  编辑姓名                     b.  编辑出生日期\n");printf("c.  编辑是否健在                  d.  编辑是否已婚\n");ch = getchar();//接收输入while(getchar() != '\n')//清空缓冲区{continue;}return ch;//返回输入选项,启动相关函数调用
}ElemType Input()
{ElemType p;  //定义个结构体变量,用于初始化调用此函数时的成员信息printf("成员姓名:");gets(p.name);  //接收姓名printf("出生日期:");gets(p.bothDay);  //接收出生日期printf("成员住址:");gets(p.address);  //接收住址printf("是否结婚(0/1):");  //0代表未婚,1代表已婚scanf("%d",&p.getMatings);  //接收是否结婚getchar();printf("是否健在(0/1):");//0代表死亡,1代表健在scanf("%d",&p.keepAlive);  //接收是否健在 getchar();if(p.keepAlive == 0)   //若死亡,接收死亡日期{printf("死亡日期:");gets(p.deathDay);  }return p;  //返回结构体变量,初始化此成员的基本个人信息
}void Init(CTree *tree)  //初始化
{printf("请确定初始化家谱信息需要的成员数量:");scanf("%d",&tree->n);  //接收初始化的时候的成员数printf("请依次输入各个人的信息:\n\n");tree->r = 0;    //根结点在数组中的位置!!!for(int i=0; i<tree->n; i++)   //循环完善每个成员的信息,包括其孩子和父亲{printf("***********\t正在完善第%d个成员的信息:\t***********\n",i+1);// printf("正在完善第%d个人的信息:\n",i+1);fflush(stdin);  //刷新缓冲区tree->nodes[i].data = Input();  //调用Input()函数,初始化此成员信息  tree->nodes[i].firstchild = NULL;  //初始化此成员的孩子域为NULLtree->nodes[i].parent = -1;  //初始化此成员的父亲在数组中的位置为-1,即为祖先Add_Child(tree, i);  //调用初始化此成员的孩子信息Add_Parent_Init(tree, i); //调用函数初始化此成员的父亲信息printf("**********************************************\n");}
}void show_seniority(CTree *tree, int label)  //label为此人在数组中的位置
{int book[MAX_TREE_SIZE] = {0};  //存入数组中每个成员的辈分int flag;  //标记成员的父亲在数组中的下标int cnt = 0;  //根据cnt的值得出此成员的辈分for (int i = 0; i < tree->n; i++)   //用迭代替代递归实现,遍历树形结构的家谱普{flag = tree->nodes[i].parent;   while(flag != -1)  //如果还没有到祖先节点,接继续执行循环体{flag = tree->nodes[flag].parent;cnt++;}book[i] = cnt+1;  //第i个成员的辈分cnt = 0; }printf("此人所在辈分是:%d\n",book[label]);
}Status Exist_Name(CTree *tree)  //以姓名查询是否存在此人
{int cnt = 0;  //统计此人孩子的个数int flag;   //得到这个人的此时此刻查询的孩子在数组的下标char demo[LEN];  //接收需要查询人的姓名printf("输入你要找的人的名字:");gets(demo); ChildPtr * p = NULL;  //输出其孩子信息int book[MAX_TREE_SIZE] = {0};  //防止重复输出相同孩子信息for(int i=0; i<tree->n; i++){if(!strcmp(tree->nodes[i].data.name, demo))  //找到是否存在此人{printf("查询结果:\n");p = tree->nodes[i].firstchild;  //指向该成员的孩子域while(p != NULL){flag = p->child; //得到其孩子在数组中的位置if(!book[flag])  //如果这个孩子没有输出过的花,则输出其孩子信息{printf("其第%d个孩子的名字是: ",cnt+1);puts(tree->nodes[flag].data.name);  //输出后自动换行book[flag] = 1;cnt++;//统计这个成员的孩子数}p = p->next;       //指向下一个孩子}if(cnt == 0)  //如果这个孩子数为0{printf("此人目前还没有孩子!\n");}if(-1 == tree->nodes[i].parent)  //如果他是祖先的话,则父亲未知{printf("家族祖先,其父亲目前尚未知悉!\n");show_seniority(tree, i);   //调用显示其辈分的函数return OK;  //返回操作成功}printf("其父亲的名字是: ");puts(tree->nodes[(tree->nodes[i].parent)].data.name);show_seniority(tree, i);   //调用显示其辈分的函数return OK;}}printf("查询结果:\n此家谱中没有此人!\n");return ERROR;  //如果在数组中没有找到这个人的姓名,返回查询失败ERROR
}Status Exist_BothDay(CTree *tree)  //以出生日期判断是否存在此人
{int cnt = 0;   //统计孩子数int flag;  //得到此节点的孩子在数组的位置int exist = 0;   int sum = 0; //统计满足此生日的人数int book[MAX_TREE_SIZE] = {0}; //标记此成员已经是否被输出过char demo[LEN];  //接收输入printf("输入你要找的人的生日:");gets(demo); ChildPtr * p =NULL;printf("查询结果:\n");for(int i=0; i<tree->n; i++)  //循环查询满足此生日的成员{if(!strcmp(tree->nodes[i].data.bothDay, demo))  //如果发现有满足这个出生日期的{exist = 1;  //标记存在printf("满足此生日的第%d个人是",sum+1);puts(tree->nodes[i].data.name);p = tree->nodes[i].firstchild;  //指向此人的孩子域while(p != NULL)  //如果他有孩子的话{flag = p->child;  //为了防止重复输出,故标记之if(!book[flag]){printf("其第%d个孩子的名字是: ",cnt+1);puts(tree->nodes[flag].data.name);  //输出后自动换行book[flag] = 1;  //他被输出过,标记为1cnt++;  //统计孩子个数}p = p->next;        //指向下一个孩子域}if(cnt == 0)  //如果这个人没有孩子{printf("此人目前还没有孩子!\n");}if(-1 == tree->nodes[i].parent)  //如果他的父亲在数组中的位置为-1,则此人为祖先{printf("家族祖先,其父亲目前尚未知悉!\n");}else{printf("其父亲的名字是: ");puts(tree->nodes[(tree->nodes[i].parent)].data.name);}sum++;  //继续查询其他人还有满足此出生日期的show_seniority(tree, i);   //调用显示其辈分的函数}cnt = 0;  //查询其他人的是否,把统计孩子的变量赋值为0}if(!exist)  //如果数组中没有满足此生日的人{printf("此家谱中没有此人!\n");return ERROR;  //返回ERROR,查询失败}return OK;  //反之,查询操作成功!
}void Inquire(CTree *tree) //查询功能
{int status; //根据返回值反馈操作是否成功int choice;  //接收用户的选项while((choice = get_choice_Inquire()) != 'q'){switch (choice){case 'a':   status = Exist_Name(tree);  //调用按照姓名查询功能if(status)  //如果成功查询{printf("查询操作成功!\n");}break;case 'b':status = Exist_BothDay(tree);  //调用按照出生日期查询功能if(status)  //如果成功查询{printf("查询操作成功!\n");}break;case 'q':default:break;}}}void Add_Child(CTree *tree, int i)  //为数组节点增加孩子 
{int sum;ChildPtr * ptr = NULL;printf("正在准备为第%d个成员完善->孩子<-信息\n",i+1);fflush(stdin);  //刷新缓冲区printf("请输入该成员的孩子数量:");scanf("%d",&sum);   //接收该成员的个数getchar();   ///接收换行符号if(sum != 0) {for(int j=0; j<sum; j++)  //确定每个孩子在数组中的位置{ptr = (ChildPtr*)malloc(sizeof(ChildPtr));if(ptr == NULL){printf("分配内存失败!程序终止!");exit(-1);}else{printf("请输入第%d个->孩子<-在数组中的<下标>:",j+1);scanf("%d",&ptr->child);  //接收该孩子在数组中的下标getchar();ptr->next = tree->nodes[i].firstchild;  //是该成员的孩子域指向此孩子的位置tree->nodes[i].firstchild = ptr;//更新下一个孩子的信息ptr = NULL;}}}else{printf("此人目前还没有孩子!\n");}        
}void Add_Parent_Init(CTree *tree, int i)  //为数组节点确定父节点 
{int flag;  //接收此成员父亲在数组的下标if(i == tree->r)  //数组下标为0,为祖先{tree->nodes[i].parent = -1;}else{fflush(stdin);  //刷新缓冲区printf("请输入第%d个节点的->父亲<-在数组中的<下标>:",i+1);scanf("%d",&flag);  //接收父亲在数组中的下标getchar();tree->nodes[i].parent = flag;}
}
/*** 新增加的成员其父亲的初始化和刚刚初始化的时候成员其父亲的初始化有不同之处,不能简单的* 像初始化其孩子一样,初始化成员的时候其父亲初始化属于创建单链表,而此时为新增加的成员* 初始化其父亲,相当于单链表的插入操作!*/
void Add_Parent_Person(CTree *tree, int i)
{ChildPtr * ptr = NULL;  //同步更新父节点的孩子链表int flag;  //此节点父节点所在数组的下标fflush(stdin);printf("请输入第%d个新成员的->父亲<-在数组中的<下标>:",i+1);scanf("%d",&flag);  //接收父亲节点在数组中位置getchar();tree->nodes[i].parent = flag;  //为此成员的父亲元素填充此父亲节点在数组中的下标ptr = (ChildPtr*)malloc(sizeof(ChildPtr));if(ptr == NULL){printf("分配内存失败!程序终止!");exit(-1);}else{ptr->child = i;  //更新父亲节点中孩子的指针域,即为父亲节点的孩子域中添加这个新的成员孩子ptr->next = tree->nodes[flag].firstchild;tree->nodes[flag].firstchild = ptr;}
}
Status Add_Person(CTree *tree)
{int sum;  //确定新增加成员的人数int cnt = tree->n;  //之前已经存在的人数printf("输入你准备增加的人数:");scanf("%d",&sum);getchar();tree->n += sum;  //更新总人数printf("请依次输入各个人的信息:\n");for(int i=0; i<sum; i++)   //为每一个新成员完善信息{printf("***********\t正在完善第%d个新成员的信息:\t***********\n",i+1);fflush(stdin);  //刷新缓冲区tree->nodes[cnt+i].data = Input();  //调用函数,初始化新增成员的个人基本信息tree->nodes[cnt+i].firstchild = NULL;  //tree->nodes[cnt+i].parent = -1;Add_Child(tree, cnt+i);Add_Parent_Person(tree, cnt+i);printf("**************************************************\n");}return OK;  //如果成功添加
}Status Remove(CTree *tree)  //删除某人
{int cnt = 0;printf("请输入要从家谱中移除的姓名:");int flag;  //确定要删除的人在数组中的下标int exist = 0;  //判断此人是否在家谱中存在char demo[LEN];//接收要删除人的姓名gets(demo); for(int i=0; i<tree->n; i++){if(!strcmp(tree->nodes[i].data.name, demo))  //判断此数组中有没有要删除的人{flag = i;exist = 1; //标记,说明此数组中存在这个人break;}}if(exist)  //如果存在这个人的话{for(int i=flag; i<tree->n; i++){tree->nodes[i] = tree->nodes[i+1];  //让这个人所在数组中后面的人往期移一个位置}tree->n--;return OK;  //删除操作成功}return ERROR;   //没有找到这个人,删除操作失败
}   Status Modify(CTree *tree)  //修改某人信息
{int flag = -1; char demo[LEN];  //接收要删除人的姓名printf("输入你要修改的人的名字:");gets(demo); for(int i=0; i<tree->n; i++){if(!strcmp(tree->nodes[i].data.name, demo))  //查找是否存在此人{flag = i;  //接收这个人在数组中下标位置break;}}if(flag == -1)  //如果数组中没有这个人{return ERROR;  //修改操作失败}int choice;  //接收选项memset(demo, '0', LEN);  //初始化该数组while((choice = get_choice_Modify()) != 'q'){switch (choice){case 'a':printf("请重新编辑此人姓名:");gets(demo);strcpy(tree->nodes[flag].data.name, demo);break;case 'b':printf("请重新编辑此人出生日期:");gets(demo);strcpy(tree->nodes[flag].data.bothDay, demo);  //把新的名字赋值给该成员break;case 'c':printf("请重新编辑此人是否健在:");scanf("%d",&tree->nodes[flag].data.keepAlive);   //更新此人是否健在状况getchar();if(tree->nodes[flag].data.keepAlive == 0)  //如果其死亡{printf("输入死亡日期:");gets(tree->nodes[flag].data.deathDay);    //更新此人的死亡日期}break;case 'd':printf("请重新编辑此人编辑是否已婚:");scanf("%d",&tree->nodes[flag].data.getMatings);  //更新此人是否已婚getchar();break;case 'q':default:break;}}return OK;
}
/*** 对一个成员数组按照出生日期进行排序,应该慎重的选择排序算法,此处相当于桶排序,因为不能让成员在数组* 中的位置发生变化,否则其孩子将失效,并且也不能单独改变生日在数组中下标,所以此处一些常见的排序算法* 我目前不知如何应用,故采用桶排序远离,去创建一个数组,其下标从小到大顺序存储按照生日排序成员在数组中过的* 下标位置*/ 
Status Sort_BothDay(CTree *tree)  //对家谱里的人进行排序
{int sort[MAX_TREE_SIZE] = {0};  //该数组用于接收排序后的成员的下标值char min_string[MAX_TREE_SIZE] = {'\0'};int min_int;int book[MAX_TREE_SIZE] = {0};  //用于标记已经排好序的成员int i = 0;int cnt = 0;  //统计排好序的人数while(i < tree->n)  {min_int = i;strcpy(min_string, tree->nodes[i].data.bothDay);while(book[i] != 0){i++;    //检索数组下标min_int = i;    //假设此时最小成员的数组下标为istrcpy(min_string, tree->nodes[i].data.bothDay);  }for(int j=0; j<tree->n; j++){if((book[j]==0)&&(i!=j)&&strcmp(min_string, tree->nodes[j].data.bothDay)>0){min_int = j;strcpy(min_string, tree->nodes[j].data.bothDay);}}sort[cnt++] = min_int;book[min_int] = 1;i = 0;if(cnt == tree->n){break;}}printf("按出生日期进行排序:\n");for (int i = 0; i < tree->n; i++){printf("第%d个人是%s,他的出生日期为:%s\n",i+1, tree->nodes[sort[i]].data.name,tree->nodes[sort[i]].data.bothDay);}return OK;  //排序操作成功,返回操作成功!
}void Destroy(CTree *tree)
{ChildPtr * p = NULL;ChildPtr * q = NULL;for (int i = 0; i < tree->n; i++){p = tree->nodes[i].firstchild;q = p;while(p){p = p->next;free(q);q = p;}}
} void Data_write(CTree *tree)
{printf("👇即将把数据存入文本文件中>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");const char *file = "homefamily.txt";ofstream outfile(file, ios::trunc);if(!outfile){printf("文件打开失败!\n");exit(-1);   }else{outfile<<"成员姓名"<<"\t"<<"出生日期"<<"\t"<<"家庭地址"<<endl;for (int i = 0; i < tree->n; i++){   outfile<<tree->nodes[i].data.name<<"\t"<<tree->nodes[i].data.bothDay<<"\t"<<tree->nodes[i].data.address<<endl;}outfile.close();printf("程序数据写入文件成功!!\n");}
}

主函数:treeco.cpp

#include "treeheader.h"
int main()
{CTree ctree;User_login(&ctree);  //用户登录函数return 0;
}

运行示例:

➜  TreeDemo g++ implements.cpp treeco.cpp -o Tree
➜  TreeDemo ./Tree
***********     欢迎登陆家族管理系统    ***********
warning: this program uses gets(), which is unsafe.
输入您的用户名:user_super
请输入管理员密码:123123欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
a
请确定初始化家谱信息需要的成员数量:4
请依次输入各个人的信息:***********     正在完善第1个成员的信息:       ***********
成员姓名:jia
出生日期:19991005
成员住址:nanjing
是否结婚(0/1):0
是否健在(0/1):1
正在准备为第1个成员完善->孩子<-信息
请输入该成员的孩子数量:2
请输入第1->孩子<-在数组中的<下标>:1
请输入第2->孩子<-在数组中的<下标>:2
**********************************************
***********     正在完善第2个成员的信息:       ***********
成员姓名:yi
出生日期:19960405
成员住址:chengdu
是否结婚(0/1):1
是否健在(0/1):1
正在准备为第2个成员完善->孩子<-信息
请输入该成员的孩子数量:1
请输入第1->孩子<-在数组中的<下标>:3
请输入第2个节点的->父亲<-在数组中的<下标>:0
**********************************************
***********     正在完善第3个成员的信息:       ***********
成员姓名:bing
出生日期:20040503
成员住址:beijing
是否结婚(0/1):1
是否健在(0/1):1
正在准备为第3个成员完善->孩子<-信息
请输入该成员的孩子数量:0
此人目前还没有孩子!
请输入第3个节点的->父亲<-在数组中的<下标>:0
**********************************************
***********     正在完善第4个成员的信息:       ***********
成员姓名:ding
出生日期:19991005
成员住址:shanghai
是否结婚(0/1):0
是否健在(0/1):1
正在准备为第4个成员完善->孩子<-信息
请输入该成员的孩子数量:0
此人目前还没有孩子!
请输入第4个节点的->父亲<-在数组中的<下标>:1
**********************************************欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
f 
按出生日期进行排序:
第1个人是yi,他的出生日期为:199604052个人是jia,他的出生日期为:199910053个人是ding,他的出生日期为:199910054个人是bing,他的出生日期为:20040503
排序操作成功!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
c
输入你准备增加的人数:2
请依次输入各个人的信息:
***********     正在完善第1个新成员的信息:     ***********
成员姓名:wu    
出生日期:20050401
成员住址:chongqing
是否结婚(0/1):1
是否健在(0/1):1
正在准备为第5个成员完善->孩子<-信息
请输入该成员的孩子数量:1
请输入第1->孩子<-在数组中的<下标>:3
请输入第5个新成员的->父亲<-在数组中的<下标>:1
**************************************************
***********     正在完善第2个新成员的信息:     ***********
成员姓名:hua
出生日期:20050401
成员住址:suzhou
是否结婚(0/1):1
是否健在(0/1):1
正在准备为第6个成员完善->孩子<-信息
请输入该成员的孩子数量:1
请输入第1->孩子<-在数组中的<下标>:6
请输入第6个新成员的->父亲<-在数组中的<下标>:-1
**************************************************
添加新成员成功!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
h
👇即将把数据存入文本文件中>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
程序数据写入文件成功!!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
c
输入你准备增加的人数:2
请依次输入各个人的信息:
***********     正在完善第1个新成员的信息:     ***********
成员姓名:cao
出生日期:20060504
成员住址:nantong
是否结婚(0/1):1
是否健在(0/1):1
正在准备为第7个成员完善->孩子<-信息
请输入该成员的孩子数量:0
此人目前还没有孩子!
请输入第7个新成员的->父亲<-在数组中的<下标>:5
**************************************************
***********     正在完善第2个新成员的信息:     ***********
成员姓名:shu
出生日期:20040504
成员住址:xuzhou
是否结婚(0/1):1
是否健在(0/1):1
正在准备为第8个成员完善->孩子<-信息
请输入该成员的孩子数量:0
此人目前还没有孩子!
请输入第8个新成员的->父亲<-在数组中的<下标>:-1
**************************************************
添加新成员成功!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
h
👇即将把数据存入文本文件中>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
程序数据写入文件成功!!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
e
输入你要修改的人的名字:ding
欢迎使用此家族管理系统的修改系统!!!
a.  编辑姓名                     b.  编辑出生日期
c.  编辑是否健在                  d.  编辑是否已婚
a
请重新编辑此人姓名:xiaoming
欢迎使用此家族管理系统的修改系统!!!
a.  编辑姓名                     b.  编辑出生日期
c.  编辑是否健在                  d.  编辑是否已婚
q
修改此人操作成功!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
h
👇即将把数据存入文本文件中>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
程序数据写入文件成功!!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
d
请输入要从家谱中移除的姓名:shu
删除此人操作成功!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
h
👇即将把数据存入文本文件中>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
程序数据写入文件成功!!欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
g欢迎使用此家族管理系统!!!
*************************************
Enter the letter of your choice:
a.  初始化家族谱                b.  查询信息
c.  增加新成员                  d.  删除成员
e.  修改成员                    f.  按生日进行排序
g.  释放内存                    h.  存入文本文件
**************q.    退出程序***********
q

图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1383431.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于C++实现家谱管理系统

1. 分析 1.1 背景分析 家谱管理系统是一个社会不可缺少的部分&#xff0c;它对于家族中的各个人、社会、历史学家等来说都至关重要&#xff0c;所以一个良好的家谱管理系统应该能够为用户提供充足的信息和功能。家谱系统对于家族和历史学家研究家族的发展有极其重要的作用。随…

【jackson】自定义字段注解完成序列化逻辑

目录 背景本文开发环境介绍新建一个注解新建一个JavaBean新建一个JsonSerializer新建一个AnnotationIntrospector单元测试总结 背景 Spring默认的JSON序列化工具使用的是jackson&#xff0c;GitHub项目地址: https://github.com/FasterXML/jackson 我们在处理前后端接口交互的…

Amazon CloudFront 部署小指南(五)- 使用 Amazon 边缘技术优化游戏内资源更新发布...

内容简介 游戏内资源包括玩家的装备/弹药/材料等素材&#xff0c;对游戏内资源的发布和更新是游戏运营商的一个常规业务流程&#xff0c;使用频率会十分高&#xff0c;所以游戏运营商希望该流程可以做到简化和可控。针对这个需求&#xff0c;我们设计了 3 个架构&#xff0c;面…

Adobe2021/20年11月更新推送

以下更新vposy带来的Adobe11月份更新推送&#xff0c;是部分小版本BUG修复更新&#xff0c;安装新版的建议更新一下以获取更好的使用体验&#xff0c;软件获取方式位于为文末。 版本更新简要 Photoshop 22.0.1 此更新包含对多个崩溃问题和工作流程错误的修复 After Effects…

Adobe 系列软件安装及激活异常解决方法

很多小伙伴安装 Adobe 的软件出现这样那样的的异常&#xff0c;希望通过这篇文章&#xff0c;可以帮大家解决问题。 安装前需要做什么&#xff1f; 如果安装过其它版本的 Adobe 软件&#xff0c;请使用 Adobe 官网卸载工具Adobe Creative Cloud Cleaner Tool卸载干净&#xf…

Adobe2021 4月份更新推送

前言 今天又又又给各位带来了vposy大神河蟹制作的Adobe 4月份更新推送 小编整理了一下供大家查阅&#xff0c;追新版本的可以更新一下&#xff0c;以获取更好的使用体验 大多更新都是提升稳定性修复Bug…… 配置要求 新版本整体对系统要求最低为Win10的1903版本&#xff0…

【EM算法推导】

# 一、必备的基础知识 EM算法用到了大量的概率论与数理统计的知识&#xff0c;必须对基础有一定掌握才能完成EM算法的推导。 ## 1.1 最大似然估计 思想&#xff1a;我们观测到了一组样本&#xff0c;为什么我们能观测到这一组样本呢&#xff1f;因为这一组样本出现的概率比较大…

18-有假币

题目 居然有假币&#xff01; 现在猪肉涨了&#xff0c;但是农民的工资却不见涨啊&#xff0c;没钱怎么买猪肉啊。nowcoder这就去买猪肉&#xff0c;结果找来的零钱中有假币&#xff01;&#xff01;&#xff01;可惜nowcoder 一不小心把它混进了一堆真币里面去了。只知道假币…

Java项目-苍穹外卖-Day03

员工分页查询功能实现 需求分析和设计 代码开发 先设计类 将对应分页查询的传参类以及结果类进行封装 对应真正返回的为Result<PageResult>Controller /**** param employeePageQueryDTO* return*/GetMapping("/page")ApiOperation("员工分页查询&qu…

什么是CSS Grid布局?什么是Flexbox布局?它们两者有什么不同?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS Grid布局⭐ Flexbox布局⭐ 不同之处⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web…

QT 如何绘制圆形进度条

QT绘制圆形进度条&#xff0c;不同于QPainterPath方式&#xff0c;直接使用 drawArc 函数效果也是出奇的好&#xff01; void Widget::paintEvent(QPaintEvent *event) {QPainter p(this);p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);QRect rc t…

android实现圆形进度条

/*** date:2021/1/4 0004* author:wsm (Administrator)* funcation:圆形进度条控件*/public class CircleProgressView extends View {private Paint mBackPaint, mProgPaint; // 绘制画笔private RectF mRectF; // 绘制区域private int[] mColorArray; // 圆环渐变色…

uniapp圆形进度条

插件下载地址&#xff1a;https://ext-resource-aliyun.dcloud.net.cn/marketplace/206a8e50-63cb-11ec-8e77-a3fa77cd6ec0/1.1.2/plugin.zip?v1668747036 一、下载并解压&#xff0c;复制到uniapp的components下 二、使用 import导入组件 import circleProgressBar from /…

超简单的Android圆形进度条

效果图&#xff1a; 代码优化/简化、教科书级别注释、复制粘贴即可用 代码&#xff1a; package com.zistone.factorytest0718.view;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; impor…

Android 绘制圆形进度条

Android 绘制圆形进度条 最近项目上有一些需求&#xff0c;需要绘制圆形的进度条满足设计上和交互上的需求&#xff1a; 实现思路 在画布上直接绘制View&#xff0c;需要了解一下几点 1.需要画一个圆 2.圆圈上有不同进度的颜色 3.圆圈中有进度数字的展示 4.圆圈中间还…

纯css制作圆形进度条

效果图大概是这样的 第一步 先定义出一个方形盒子 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…

实现一个圆形进度条(vue)

实现方式&#xff1a;首先是用svg画两个圆&#xff0c;同圆心同半径的两个圆&#xff0c;然后把颜色都设置成透明&#xff0c;利用圆的边框来实现。给两个圆设置相同的边框宽度&#xff0c;并且设置颜色&#xff08;设置一个透明&#xff0c;一个有颜色&#xff09;&#xff1b…

药都银行冲刺上交所:年营收22.78亿 古井集团是股东

雷递网 雷建平 5月1日 亳州药都农村商业银行股份有限公司&#xff08;简称&#xff1a;“药都银行”&#xff09;日前递交招股书&#xff0c;准备在上交所主板上市。 药都银行计划募资16.38亿元。 年营收22.78亿 药都银行坐落于世界中医药之都——亳州市&#xff0c;于2005年12…

自贸港首家公务机公司海航金鹿商务正式启动运营

日前&#xff0c;海航集团旗下金鹿公务在海口设立公务机总部 -- 金鹿商务航空有限公司&#xff08;简称&#xff1a;金鹿商务&#xff09;&#xff0c;已通过中国民用航空海南安全监督管理局运行审定&#xff0c;取得中国民用航空中南地区管理局颁发的运行规范。4月29日上午9时…

内网通朋友不在线

前段时间使用内网通发现同学老师的总是不在线&#xff0c;有时候改一下IP地址&#xff0c;又可以&#xff0c;后面才发现原来可以自己设置网段地址的 设置过程见下图&#xff1a; 输入老师的IP地址的前三位即可