实现如下基本功能:(为某家族(可选某文学著作中的家族)建立家谱及实现其相应查询和其他功能)建立家谱,要求家谱至少包含四代,功能包括:创建祖先,创建子女;添加家庭成员:添加子女;查询家族成员:查询人员关系;查询某人的各代子孙;直观方式输出家谱。C语言程序
时间: 2024-03-08 14:51:09 浏览: 77
好的,以下是一个基于C语言实现家谱管理程序的示例代码,实现了上述所有基本功能:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LEN 20 // 姓名最大长度
#define MAX_CHILDREN_NUM 10 // 子女最大数量
// 家庭成员结构体
typedef struct _person {
char name[MAX_NAME_LEN]; // 姓名
char gender; // 性别,M表示男性,F表示女性
char birthdate[12]; // 出生日期,格式为YYYY-MM-DD
struct _person *father; // 父亲指针
struct _person *mother; // 母亲指针
struct _person *children[MAX_CHILDREN_NUM]; // 子女指针数组
int children_num; // 子女数量
} Person;
// 全局变量,存储祖先
Person *root = NULL;
// 函数声明
void create_root(); // 创建祖先
void create_child(Person *parent); // 创建子女
void add_child(Person *parent); // 添加子女
void query_relationship(); // 查询人员关系
void query_descendants(Person *person, int level); // 查询某人的各代子孙
void print_family_tree(Person *person, int level); // 直观方式输出家谱
Person *find_person(char *name); // 根据姓名查找家庭成员
int main() {
int choice = 0;
while (1) {
printf("请选择操作:\n");
printf("1. 创建祖先\n");
printf("2. 创建子女\n");
printf("3. 添加子女\n");
printf("4. 查询人员关系\n");
printf("5. 查询某人的各代子孙\n");
printf("6. 直观方式输出家谱\n");
printf("7. 退出程序\n");
scanf("%d", &choice);
getchar(); // 消耗输入缓冲区中的回车符
switch (choice) {
case 1:
create_root();
break;
case 2:
create_child(root);
break;
case 3:
add_child(root);
break;
case 4:
query_relationship();
break;
case 5:
printf("请输入人员姓名:\n");
char name[MAX_NAME_LEN];
fgets(name, MAX_NAME_LEN, stdin);
name[strlen(name)-1] = '\0'; // 去掉输入的回车符
Person *person = find_person(name);
if (person == NULL) {
printf("找不到该人员!\n");
} else {
printf("%s的各代子孙有:\n", person->name);
query_descendants(person, 0);
}
break;
case 6:
print_family_tree(root, 0);
break;
case 7:
printf("谢谢使用,再见!\n");
exit(0);
default:
printf("无效的选择,请重新输入!\n");
}
}
return 0;
}
// 创建祖先
void create_root() {
if (root != NULL) {
printf("家谱已存在!\n");
return;
}
root = (Person *)malloc(sizeof(Person));
printf("请输入祖先姓名:\n");
fgets(root->name, MAX_NAME_LEN, stdin);
root->name[strlen(root->name)-1] = '\0'; // 去掉输入的回车符
printf("请输入祖先性别(M/F):\n");
scanf("%c", &root->gender);
getchar(); // 消耗输入缓冲区中的回车符
printf("请输入祖先出生日期(格式为YYYY-MM-DD):\n");
fgets(root->birthdate, 12, stdin);
root->birthdate[strlen(root->birthdate)-1] = '\0'; // 去掉输入的回车符
root->father = NULL;
root->mother = NULL;
root->children_num = 0;
printf("祖先%s创建成功!\n", root->name);
}
// 创建子女
void create_child(Person *parent) {
if (parent == NULL) {
printf("请先创建祖先!\n");
return;
}
if (parent->gender == 'M') {
printf("只有女性可以生育!\n");
return;
}
if (parent->children_num >= MAX_CHILDREN_NUM) {
printf("%s的子女已达到最大数量!\n", parent->name);
return;
}
Person *child = (Person *)malloc(sizeof(Person));
printf("请输入子女姓名:\n");
fgets(child->name, MAX_NAME_LEN, stdin);
child->name[strlen(child->name)-1] = '\0'; // 去掉输入的回车符
printf("请输入子女性别(M/F):\n");
scanf("%c", &child->gender);
getchar(); // 消耗输入缓冲区中的回车符
printf("请输入子女出生日期(格式为YYYY-MM-DD):\n");
fgets(child->birthdate, 12, stdin);
child->birthdate[strlen(child->birthdate)-1] = '\0'; // 去掉输入的回车符
child->father = parent;
child->mother = NULL;
child->children_num = 0;
parent->children[parent->children_num] = child;
parent->children_num++;
printf("子女%s创建成功!\n", child->name);
}
// 添加子女
void add_child(Person *parent) {
if (parent == NULL) {
printf("请先创建祖先!\n");
return;
}
if (parent->children_num >= MAX_CHILDREN_NUM) {
printf("%s的子女已达到最大数量!\n", parent->name);
return;
}
printf("请输入子女姓名:\n");
char name[MAX_NAME_LEN];
fgets(name, MAX_NAME_LEN, stdin);
name[strlen(name)-1] = '\0'; // 去掉输入的回车符
Person *child = find_person(name);
if (child == NULL) {
printf("找不到该人员!\n");
} else {
if (child->father != NULL || child->mother != NULL) {
printf("%s已有父母,不能再添加子女!\n", child->name);
} else {
if (parent->gender == 'M') {
child->mother = parent;
} else {
child->father = parent;
}
parent->children[parent->children_num] = child;
parent->children_num++;
printf("子女%s添加成功!\n", child->name);
}
}
}
// 查询人员关系
void query_relationship() {
printf("请输入人员1姓名:\n");
char name1[MAX_NAME_LEN];
fgets(name1, MAX_NAME_LEN, stdin);
name1[strlen(name1)-1] = '\0'; // 去掉输入的回车符
printf("请输入人员2姓名:\n");
char name2[MAX_NAME_LEN];
fgets(name2, MAX_NAME_LEN, stdin);
name2[strlen(name2)-1] = '\0'; // 去掉输入的回车符
Person *person1 = find_person(name1);
Person *person2 = find_person(name2);
if (person1 == NULL || person2 == NULL) {
printf("找不到某个人员!\n");
} else {
if (person1 == person2) {
printf("%s和%s是同一个人!\n", name1, name2);
} else {
int generation1 = 0, generation2 = 0;
Person *p1 = person1, *p2 = person2;
while (p1 != root) {
generation1++;
p1 = p1->father;
}
while (p2 != root) {
generation2++;
p2 = p2->father;
}
if (generation1 < generation2) {
for (int i = 0; i < generation2 - generation1; i++) {
person2 = person2->father;
}
} else {
for (int i = 0; i < generation1 - generation2; i++) {
person1 = person1->father;
}
}
while (person1 != person2) {
person1 = person1->father;
person2 = person2->father;
}
printf("%s和%s的关系为:", name1, name2);
for (int i = 0; i < generation1 - 1; i++) {
printf("曾");
}
for (int i = 0; i < generation2 - 1; i++) {
printf("祖");
}
if (generation1 == 1 && generation2 == 1) {
printf("夫妻\n");
} else if (generation1 == generation2) {
printf("兄弟姐妹\n");
} else if (generation1 < generation2) {
printf("伯叔姑婆\n");
} else {
printf("子孙\n");
}
}
}
}
// 查询某人的各代子孙
void query_descendants(Person *person, int level) {
for (int i = 0; i < level; i++) {
printf(" ");
}
printf("%s\n", person->name);
for (int i = 0; i < person->children_num; i++) {
query_descendants(person->children[i], level+1);
}
}
// 直观方式输出家谱
void print_family_tree(Person *person, int level) {
for (int i = 0; i < level; i++) {
printf(" ");
}
printf("%s\n", person->name);
for (int i = 0; i < person->children_num; i++) {
print_family_tree(person->children[i], level+1);
}
}
// 根据姓名查找家庭成员
Person *find_person(char *name) {
if (root == NULL) {
return NULL;
}
if (strcmp(root->name, name) == 0) {
return root;
}
for (int i = 0; i < root->children_num; i++) {
Person *person = find_person_in_subtree(root->children[i], name);
if (person != NULL) {
return person;
}
}
return NULL;
}
// 在子树中查找家庭成员
Person *find_person_in_subtree(Person *person, char *name) {
if (strcmp(person->name, name) == 0) {
return person;
}
for (int i = 0; i < person->children_num; i++) {
Person *p = find_person_in_subtree(person->children[i], name);
if (p != NULL) {
return p;
}
}
return NULL;
}
```
注意,以上代码只是一个示例,可能还需要根据实际情况进行适当修改和完善。例如,可以加入输入验证,防止用户输入无效或错误的数据;可以将家庭成员信息保存到文件中,以便下次启动程序时恢复家谱等等。
阅读全文