void FileToFamilyTree( Node *root) ; //从文件中读取 (3)实现方法:文件流 (4)实现结果: (三)数据结构实现 1、生日结构体 struct BirthDay { int year; int month; int day; friend istream& operator>>(istream &is,BirthDay &b); friend ostream& operator<<(ostream &os,const BirthDay &b); }; 2、信息结构体(家族成员的基本信息) struct Information { string name; //姓名 string birthPlace; //出生地 BirthDay birthDay; // 生日 string sex; //性别 string education; //学历 string job; //工作 string father; //父亲 string spouse; //配偶 char life; //是否健在 }; 3、二叉树结点结构体 struct Node { Information data; //个人信息 Node* child; //第一个孩子 Node* brother; //兄弟 }; 4、家谱类(二叉树结构、左孩子,右兄弟) class FamilyTree { private: Node* root; Node* Creat( ); //构造函数调用 void Release(Node *root); //析构函数调用 static int Numberofpeople; //计算总人数, NumberOfPeople()调用 static int LifePeopele; //计算健在人数, LifeNum ()调用 public: FamilyTree(); //构造函数,初始化一棵树,其前序序列由键盘输入 ~FamilyTree(); //析构函数,释放链表中各结点的存储空间 void SetNode(Node *root); //设置结点信息 Node* Getroot(); //获取根结点 void PreOrder(Node *root); //前序递归遍历输出家谱 void InOrder(Node *root); // 中序递归遍历输出家谱 void PostOrder(Node *root); //后序递归遍历输出家谱 int Generation(Node *root); //这个家族共有几代人 int NumberOfPeople( ); //家族的总人数 int LifeNum( ); //健在人数 void PrintMessage(Node *root ); //输出基本信息 int Message(Node *root,string Name); //显示该成员的基本信息 Node* PreFindFather(Node *root,string FatherName); //给定元素值查找父 亲结点指针位置并返回其指针,此方法采用的先序遍历 Node* PreFindBrother(Node *root,string FatherName); //给定元素值查找 兄弟结点指针位置并返回其指针,此方法采用的先序遍历 void AddNewPeople(Node *root,string FatherName,string NAme); //增加新的 家族成员 int DeletePeople(Node *root,string FatherName,string Deletepeople); //删除家 族成员 int SetNewName(Node *root,string NAme,string NewName); //更改姓名 int FindChild(Node *root,string NAme); //显示孩子信息 void SaveToFile(Node *root); //保存到文件 11 void FileToFamilyTree( Node *root) ; //从文件中读取 }; (四)调试分析 1、问题:在创建家谱时,询问用户是否需要继续添加成员,只要用户不输入“#”就继续添加。 解决方案:增加if语句判断条件,只要输入的不是“Y”,“y”,“#”,就请用户重新输入。 2、问题:计算总人数和健在人数,因为存在增加和删除函数,多次调用计算函数。 解决方案:在家谱类中使用静态成员变量 3、问题:在输入和输出成员信息中的生日,生日使用的是生日结构体变量,输入输出包括年、月、日。 解决方案:使用友元输入输出重载 4、问题:在输入生日时,输入数字程序正常运行,输入其他字符,程序会出现死循环。 解决方案: cin.fail( ) 判断输入是否正确, cin.clear( ) 为了使输入错误能重新输入,将错误标识符改为 0,cin.sync( ) 清空流。 5、问题:在输入一些信息是,询问用户是否确认一些信息时,请用户输入“y”、“n”,但是用户有时会输入大写。 解决方案:使用 toupper( ) 函数,将用户输入的确认信息转换成大写字母。 6、问题:在增加孩子时,只能添加长子,添加第二个孩子、第三个等等,会出现错误。 解决方案:添加一个寻找兄弟指针的函数,如果要添加孩子的成员,已经有了孩子,则通过调用兄弟指针函数来增加孩子。 7、问题:保存到文件和读取文件时,会出现输入路径错误的情况。 解决方案:通过调用 _access( ) 函数,判断输入路径是否正确。 8、问题:读取文件时,cin的>>重载会跳过空白字符,包括回车符。 解决问题:使用 cin.get( ) 函数接收回车。 9、问题:删除成员时,删除能够成功,但会出现空指针错误。 解决方案:在delete该成员时,需要将指向该成员的指针置空。 10、问题:在主函数中,通过请用户输入数字,来选择相应的操作,当用户误输入的为选择以外的字符时,会结束程序运行。 解决方案:与解决方案4相同。 (五)实验结果及分析 1、 创建家谱 2、 保存到文件 3、读取文件 4、 增加成员 5、 基本信息 6、 查询成员信息
家谱管理系统 - 图文
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)