文件+树,图书目录管理系统
【主要内容】
开发一个图书目录管理系统,作为图书馆系统的子系统。目录管理系统管理的对象是目录,要求是实现以下基本功能:
(1)对目录的增删查改功能
(2)对文件中保存的目录文件顺序输出
(3)输出树形目录
【数据结构】
树的存储结构,用.dat文件当作数据库。
关于文件的操作详见我的另一篇博文:
在实现阶段,由于我读题不认真(西八),没看清楚需求。在存储和读取时树和数组混用了,造成了不少代码冗余,而我又懒得改。。各位大佬将就着看看吧。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAX_TREE_SIZE 100
typedef struct Catalog { //目录结构类型
char Key[20]; //编号
char Caption[80]; //标题、类名
char Parent[20]; //父类编号
}Catalog;
typedef struct CatalogTree { //目录顺序存储结构类型
Catalog Node[MAX_TREE_SIZE];
int root; //根结点位置
int num; //最后一个结点的数组编号
}CatalogTree;
void InitTree(CatalogTree &T) //树的初始化
{
for (int i = 0; i < MAX_TREE_SIZE; i++)
{
*T.Node[i].Caption = -1;
*T.Node[i].Key = -1;
*T.Node[i].Parent = -1;
}
T.root = 0;
T.num = 0;
}
void Initdata()
{
Catalog s[5] = {
{"0","中国图书分类","-1"},
{"A","马列主义","0"},
{"B","哲学、宗教","0"},
{"C","社会科学理论","0"},
{"A1","论十大关系","A"} };
FILE* fp = fopen("data.dat", "w+");
if (fp == NULL)
{
exit(-1);
}
fwrite((void*)s, sizeof(s), 1, fp);
fclose(fp);
}
void LoadTree(CatalogTree &T) {//从文件中读树从而构造树
FILE* fp = fopen("catalog-目录管理数据源.dat", "rb");
if (fp == NULL)
{
cout << "False" << endl;
exit(-1);
}
for (int i = 0; i <MAX_TREE_SIZE; i++)
{
fseek(fp, i * sizeof(struct Catalog), 0);
fread(&T.Node[i], sizeof(struct Catalog), 1, fp);
if (feof(fp))
{
T.num = i;
break;
}
}
fclose(fp);
/*for(int i=0;i<10;i++)
{
cout<<T.Node[i].Key<<T.Node[i].Caption<<T.Node[i].Parent<<endl;
}*/
}
void Save(CatalogTree &T) //更新文件
{
FILE* fp = fopen("catalog-目录管理数据源.dat", "wb");
for (int i = 0; i < T.num; i++)
{
fseek(fp, i * sizeof(struct Catalog), 0);
fwrite(&T.Node[i], sizeof(struct Catalog), 1, fp);
}
//fwrite(T.Node, sizeof(struct Catalog), T.num, fp);
//fscanf(fp, "%s%s%s", T.Node->Key, T.Node->Caption, T.Node->Parent);
fclose(fp);
}
void addCatalog(CatalogTree &T) //增加目录
{
Catalog *tmp = new Catalog;
cout << "Key:";
cin >> tmp->Key;
getchar();
cout << "Caption:";
cin >> tmp->Caption;
getchar();
cout << "Parent:";
cin >> tmp->Parent;
getchar();
T.Node[T.num++] = *tmp;
Save(T);
}
int Search(CatalogTree& T) //查找目录
{
int b=0;
Catalog* tmp = new Catalog;
cout << "输入要查找的目录的编号:" << "\n";
cout << "Key:";
cin >> tmp->Key;
getchar();
for (int i = 0; i < T.num; i++)
{
if (T.Node[i].Key==tmp->Key)
{
b = i;
break;
}
}
if (b == 0)
cout << "要找的目录不存在" << endl;
return b;
}
void DeleteCatalog(CatalogTree& T) //删除结点
{
int i = Search(T);
for (i; i < T.num; i++)
{
T.Node[i] = T.Node[i + 1];
}
T.num--;
Save(T);
}
void AlterCatalog(CatalogTree& T)
{
int i = Search(T);
cout << "输入要修改的内容:" << endl;
cout << "Key:";
cin >> T.Node[i].Key;
getchar();
cout << "Caption";
cin >> T.Node[i].Caption;
getchar();
cout << "Parent:";
cin >> T.Node[i].Parent;
getchar();
Save(T);
}
void PrintfCatalog(CatalogTree &T) //顺序读出
{
for (int i = 0; i < T.num; i++)
{
cout << T.Node[i].Key << T.Node[i].Caption << T.Node[i].Parent << endl;
}
cout << T.root << "\n" << T.num << "\n";
}
void CreatCatalogTree()
{
}
void PreOrder(CatalogTree& T, int k, int level)
{
int m = 0;
for (int i = 0; i < level; i++)
cout << " ";
cout << "|--" << T.Node[k].Caption << "\t" << T.Node[k].Key<<"\n";
for (int j = k + 1; j < T.num; j++)
{
if (!strcmp(T.Node[j].Parent, T.Node[k].Key))
{
m = 1;
PreOrder(T, j, level + m);
}
}
}
void PrintCatalogTree(CatalogTree &T)
{
int i = 0;
int level = 1;
PreOrder(T, i, level);
}
void menu(CatalogTree &T)
{
cout << " ************************************************* " << "\n";
cout << " 分类管理菜单 " << "\n";
cout << " ************************************************* " << "\n";
cout << "* 1.增加分类 *" << "\n";
cout << "* 2.输出分类 *" << "\n";
cout << "* 3.输出树形分类树 *" << "\n";
cout << "* 4.修改分类 *" << "\n";
cout << "* 5.删除分类 *" << "\n";
cout << "* 0.返回上级 *" << "\n";
cout << " ************************************************* " << "\n";
cout << "请输入你的选择!0-5:" << endl;
int n;
cin >> n;
switch (n) {
case 1:
addCatalog(T);
system("pause");
break;
case 2:
PrintfCatalog(T);
system("pause");
break;
case 3:
PrintCatalogTree(T);
system("pause");
break;
case 4:
AlterCatalog(T);
system("pause");
break;
case 5:
DeleteCatalog(T);
system("pause");
break;
case 0:
system("pause");
break;
default:
cout << "输入错误\n";
system("pause");
break;
}
}
int main()
{
CatalogTree T;
//Initdata();
InitTree(T);
LoadTree(T);
while (1) {
system("cls");
menu(T);
LoadTree(T);
}
return 0;
}
运行结果