一、需求分析
1、问题描述
设计一个程序模拟windows资源管理器。
2、功能需求
用户根据提示,选择预期实现的功能,并按要求操作,模拟windows资源管理器中所能实现的基本功能。
程序执行的命令包括:
(1)、程序运行,提示用户选择预期实现的功能;
(2)、用户按要求操作;
(3)、结束。
二、概要设计
1、 问题的抽象数据类型分析
本题要模拟windows资源管理器,需自己构造抽象数据类型。因对某一既定数据结构,各数据元素组成相同,则不能分别定义三类数据元素,而要把磁盘、目录、文件统一在一起。
数据域可分为三部分,data1为磁盘类的对象,data2为目录类的对象,data3为文件类的对象。若为磁盘,则data1中存储磁盘信息(磁盘名称、总大小、可用空间),data2和data3为默认“空”状态;若为目录,则data2中存储目录信息(目录名称、修改日期、大小、对象数),data1和data3为默认“空”状态;若为文件,则data3中存储文件信息(文件名、类型、创建时间、文件大小),data1和data2为默认“空”状态。
对每一个数据元素,与上级目录、下级目录、同级目录均有联系,故指针域也分为三部分。综上,设计数据元素组成如下图所示:
数据元素:ai,i=0,1,…,n-1 (n≥0),代表一个磁盘,或一个目录,或一个文件。
为非线性结构,对数据元素除第一个a0无直接前驱外, ai (0<i≤n-2)有唯一的直接前驱,而直接后继可能有多个。
2、存储结构设计
1)、存储结构的确定
对每一个数据元素,除第一个a0无直接前驱外, ai (0<i≤n-2)有唯一的直接前驱,而直接后继可能有多个,为非线性结构,故选用树存储。
对每一个数据元素,与上级目录、下级目录、同级目录均有联系,有三个指针,考虑采用二叉树。对于每一个结点(代表一个磁盘,或一个目录,或一个文件),始终将与其处于资源管理器中同一层级的结点,作为其右子树,而将在资源管理器中位于该结点下一层级的结点,作为其左子树。即parent指向上一级或同一级(第一个磁盘的parent指向空),nextlevel指向下一级(无下一级(包括文件)时指向空),equallevel指向同一级(为某一层级最后一个时指向空)。
综上所述,采用二叉树存储结构。
2)、设计二叉树
3、逻辑操作设计
(1)、构造一个空的资源管理器
(2)、新建磁盘
(3)、删除磁盘
(4)、选定磁盘
(5)、在当前选择目录下新建目录
(6)、在当前选择目录下删除目录
(7)、在当前选择目录下选定文件夹
(8)、在当前选择目录下新建文件
(9)、在当前选择目录下删除文件
(10)、输出当前目录下文件及文件夹信息
(11)、回上一级
(12)、查找目录\文件信息
(13)、撤销一个资源管理器
三、详细设计
1、磁盘类的定义:
class disk
{
public:
string dname;
float dsize;
float unusedspace;
public:
disk()
{
dname = "";
dsize = 0.0f;
unusedspace = 0.0f;
}
disk(string _dname, float _dsize = 0.0f, float _unusedspace = 0.0f)
{
dname = _dname;
dsize = _dsize;
unusedspace = _unusedspace;
}
};
2、目录类的定义:
class catalog
{
public:
string cname;
string savetime;
float csize;
int number;
public:
catalog()
{
cname = "";
savetime = "";
csize = 0.0f;
number = 0;
}
catalog(string _cname, string _savetime = "", float _csize = 0.0f, int _number = 0)
{
cname = _cname;
savetime = _savetime;
csize = _csize;
number = _number;
}
};
3、文件类的定义:
class file
{
public:
string fname;
string type;
string createtime;
float fsize;
public:
file()
{
fname = "";
type = "";
createtime = "";
fsize = 0.0f;
}
file(string _fname, string _type = "", string _createtime = "", float _fsize = 0.0f)
{
fname = _fname;
type = _type;
createtime = _createtime;
fsize = _fsize;
}
};
4、结点的定义:
struct SystemNode
{
disk data1;
catalog data2;
file data3;
SystemNode *parent, *nextlevel, *equallevel;
SystemNode()
{
parent = NULL;
nextlevel = NULL;
equallevel = NULL;
}
};
5、资源管理器类的定义及类中函数的具体实现:
class manage
{
protected:
SystemNode *root, *current;
public:
manage() //构造空的资源管理器
{
root = NULL;
current = NULL;
}
~manage()
{
deletesystem();
}
void createdisk(); //新建磁盘
void deletedisk(); //删除磁盘
void choosedisk(); //选定磁盘
void createcatalog(); //在当前选择目录下新建目录
void deletecatalog(); //在当前选择目录下删除目录
void choosecatalog(); //在当前选择目录下选定文件夹
void createfile(); //在当前选择目录下新建文件
void deletefile(); //在当前选择目录下删除文件
void printcurrent(); //以目录树的形式输出当前目录下的文件以及文件夹信息,并统计目录数和文件数
void gobacklast(); //回上一级:当前目录为当前目录的上一级目录,并以目录树的形式输出当前目录下的文件以及文件夹信息,并统计目录数和文件数
void search(); //模糊查找目录/文件信息
void deletesystem(); //撤销资源管理器
};
void manage::createdisk()
{
current = root;
if (current)
while (current->equallevel!= NULL) current = current->equallevel;
SystemNode *t;
t = current;
current = new SystemNode;
current->parent = t;
if (t)
t->equallevel = current;
else
root = current;
cout << "请输入磁盘名称、可用空间(以M为单位):(以空格隔开)"<<endl;
cin >> current->data1.dname >> current->data1.unusedspace;
cout << "新建磁盘成功!" << endl;
}
void manage::deletedisk()
{
cout << "所有磁盘为:"<<endl;
current = root;
int i = 1;
while(1)
{
cout << i << "、" << current->data1.dname << endl;
i++;
current = current->equallevel;
if (current == NULL) break;
}
cout << "您要删除的磁盘序号为:";
int t;
cin >> t;
current = root;
if (t == 1)
{
if (!root->equallevel)
{
root = NULL;
current = NULL;
cout << "您选择的磁盘已成功删除,当前资源管理器为空!" << endl;
return;
}
else
{
root = root->equallevel;
current = root;
current->parent = NULL;
}
}
else
{
SystemNode *p;
for (i = 2; i <= t; i++)
{
p = current;
current = current->equallevel;
}
if (current->equallevel)
{
p->equallevel = current->equallevel;
current->equallevel->parent = p;
}
else
p->equallevel = NULL;
}
cout << "您选择的磁盘已成功删除,当前所有磁盘为:" << endl;
current = root;
i = 1;
while (1)
{
cout << i << "、" << current->data1.dname << endl;
i++;
current = current->equallevel;
if (current == NULL) break;
}
current = root;
}
void manage::choosedisk()
{
cout << "所有磁盘为:" << endl;
current = root;
int i = 1;
while (1)
{
cout << i << "、" << current->data1.dname << endl;
i++;
current = current->equallevel;
if (current == NULL) break;
}
cout << "您要选择的磁盘序号为:";
int t;
cin >> t;
current = root;
if(t!=1)
{
for (i = 2; i <= t; i++)
current = current->equallevel;
}
cout << "已成功选择指定磁盘!" << endl;
}
void manage::createcatalog()
{
if (current->data3.fname != "")
{
cout << "当前选择的为文件,不可在其下新建目录!" << endl;
return;
}
SystemNode *t, *p,*q;
p = current;
q = current;
int n=0;
if (!current->nextlevel)
t = current;
else
{
current = current->nextlevel;
while (current->equallevel != NULL) current = current->equallevel;
t = current;
n = 1;
}
current = new SystemNode;
cout << "请输入目录名称、修改日期:(以空格隔开)"<<endl;
cin >> current->data2.cname >> current->data2.savetime ;
current->data2.csize = 0;
while (p->data1.dname == "")
{
p->data2.csize += current->data2.csize;
p = p->parent;
}
current->parent = t;
if (n==1)
t->equallevel = current;
else
t->nextlevel = current;
p->data1.dsize += current->data2.csize;
p->data1.unusedspace -= current->data2.csize;
if (q->data2.cname != "")
{
q->data2.savetime = current->data2.savetime;
q->data2.number++;
}
cout << "新建目录成功!" << endl;
}
void manage::deletecatalog()
{
if (!current->nextlevel)
{
cout << "当前选择目录下为空!" << endl;
return;
}
cout << "当前选择目录下的所有目录为:" << endl;
SystemNode *p,*q,*r;
q = current;
r = current;
current = current->nextlevel;
int i = 1;
while (1)
{
if (current->data2.cname != "")
{
cout << i << "、" << current->data2.cname << endl;
i++;
}
current = current->equallevel;
if (current == NULL) break;
}
cout << "您要删除的目录序号为:";
int t;
cin >> t;
current = q;
current = current->nextlevel;
i = 1;
while(1)
{
p = current->parent;
if (current->data2.cname != "") i++;
if (i > t) break;
current = current->equallevel;
}
if (current->equallevel)
{
if (p->nextlevel!=current)
{
p->equallevel = current->equallevel;
current->equallevel->parent = p;
}
else
{
p->nextlevel = current->equallevel;
current->equallevel->parent = p;
}
}
else
{
if (p->nextlevel!=current)
p->equallevel = NULL;
else
p->nextlevel = NULL;
}
while (r->parent)
{
r->data2.csize -= current->data2.csize;
r = r->parent;
}
r->data1.dsize -= current->data2.csize;
r->data1.unusedspace += current->data2.csize;
string s;
cout << "请输入当前时间:" << endl;
cin >> s;
if (q->data2.cname != "")
{
q->data2.savetime = s;
q->data2.number--;
}
if (!q->nextlevel)
{
cout << "您选择的目录已成功删除,当前选择目录下为空!" << endl;
return;
}
cout << "您选择的目录已成功删除,当前选择目录下的所有目录为:" << endl;
current = q;
current = current->nextlevel;
i = 1;
while (1)
{
if (current->data2.cname != "")
{
cout << i << "、" << current->data2.cname << endl;
i++;
}
current = current->equallevel;
if (current == NULL) break;
}
if (i == 1) cout << "空" << endl;
current = q;
}
void manage::choosecatalog()
{
if (!current->nextlevel)
{
cout << "当前选择目录下为空!" << endl;
return;
}
SystemNode *p;
p = current;
cout << "当前选择目录下的所有目录为:" << endl;
current = current->nextlevel;
int i = 1;
while (1)
{
if (current->data2.cname != "")
{
cout << i << "、" << current->data2.cname << endl;
i++;
}
current = current->equallevel;
if (current == NULL) break;
}
cout << "您要选择的目录序号为:";
int t;
cin >> t;
current = p;
current = current->nextlevel;
i = 1;
while (1)
{
if (current->data2.cname != "") i++;
if (i > t) break;
current = current->equallevel;
}
cout << "已成功选定指定文件夹!" << endl;
}
void manage::createfile()
{
if (current->data3.fname != "")
{
cout << "当前选择的为文件,不可在其下新建文件!" << endl;
return;
}
SystemNode *t, *p, *q;
p = current;
q = current;
int n = 0;
if (!current->nextlevel)
t = current;
else
{
current = current->nextlevel;
while (current->equallevel != NULL) current = current->equallevel;
t = current;
n = 1;
}
current = new SystemNode;
cout << "请输入文件名、类型、创建时间、文件大小(以M为单位):(以空格隔开)"<<endl;
cin >> current->data3.fname >> current->data3.type >> current->data3.createtime >> current->data3.fsize;
while (p->data1.dname == "")
{
p->data2.csize += current->data3.fsize;
p = p->parent;
}
if (p->data1.unusedspace < current->data3.fsize)
{
cout << "磁盘空间不足,文件创建失败! " << endl;
current = q;
return;
}
current->parent = t;
if (n==1)
t->equallevel = current;
else
t->nextlevel = current;
p->data1.dsize += current->data3.fsize;
p->data1.unusedspace -= current->data3.fsize;
if (q->data2.cname != "")
{
q->data2.savetime = current->data3.createtime;
q->data2.number++;
}
cout << "新建文件成功!" << endl;
}
void manage::deletefile()
{
if (!current->nextlevel)
{
cout << "当前选择目录下为空!" << endl;
return;
}
cout << "当前选择目录下的所有文件为:" << endl;
SystemNode *p, *q,*r;
q = current;
r = current;
current = current->nextlevel;
int i = 1;
while (1)
{
if (current->data3.fname != "")
{
cout << i << "、" << current->data3.fname << endl;
i++;
}
current = current->equallevel;
if (current == NULL) break;
}
cout << "您要删除的文件序号为:";
int t;
cin >> t;
current = q;
current = current->nextlevel;
i = 1;
while(1)
{
p = current->parent;
if (current->data3.fname != "") i++;
if (i > t) break;
current = current->equallevel;
}
if (current->equallevel)
{
if (p->nextlevel!=current)
{
p->equallevel = current->equallevel;
current->equallevel->parent = p;
}
else
{
p->nextlevel = current->equallevel;
current->equallevel->parent = p;
}
}
else
{
if (p->nextlevel!=current)
p->equallevel = NULL;
else
p->nextlevel = NULL;
}
while (r->parent)
{
r->data2.csize -= current->data3.fsize;
r = r->parent;
}
r->data1.dsize -= current->data3.fsize;
r->data1.unusedspace += current->data3.fsize;
string s;
cout << "请输入当前时间:" << endl;
cin >> s;
if (q->data2.cname != "")
{
q->data2.savetime = s;
q->data2.number--;
}
if (!q->nextlevel)
{
cout << "您选择的文件已成功删除,当前选择目录下为空!" << endl;
return;
}
cout << "您选择的文件已成功删除,当前选择目录下的所有文件为:" << endl;
current = q;
current = current->nextlevel;
i = 1;
while (1)
{
if (current->data3.fname != "")
{
cout << i << "、" << current->data3.fname << endl;
i++;
}
current = current->equallevel;
if (current == NULL) break;
}
if (i == 1) cout << "空" << endl;
current = q;
}
void manage::printcurrent()
{
SystemNode *t;
t = current;
int cnum=0, fnum=0;
if (current->data1.dname != "")
cout << "--- 磁盘 " << current->data1.dname<<" 总大小:"<<current->data1.dsize << "M" << " 可用空间:" <<current->data1.unusedspace << "M" << endl;
else if (current->data2.cname != "")
cout << "--- 文件夹 " << current->data2.cname << " 修改日期:" <<current->data2.savetime << " 大小:" <<current->data2.csize << "M" <<" 对象数:"<<current->data2.number<< endl;
else
cout << "--- 文件 " << current->data3.fname << " 类型:" <<current->data3.type << " 创建时间:" <<current->data3.createtime << " 大小:" <<current->data3.fsize<<"M"<< endl;
if (!current->nextlevel) return;
current = current->nextlevel;
while (current)
{
if (current->data2.cname != "")
{
cout << "--------- 文件夹 " << current->data2.cname << " 修改日期:" << current->data2.savetime << " 大小:" << current->data2.csize << "M" << " 对象数:" << current->data2.number << endl;
cnum++;
}
else
{
cout << "--------- 文件 " << current->data3.fname << " 类型:" << current->data3.type << " 创建时间:" << current->data3.createtime << " 大小:"<< current->data3.fsize << "M" << endl;
fnum++;
}
current = current->equallevel;
}
cout << "该目录下共有" << cnum << "个文件夹," << fnum << "个文件" << endl;
current = t;
}
void manage::gobacklast()
{
if (current->data1.dname != "")
{
cout << "当前已为磁盘,无上级目录!" << endl;
return;
}
while (current->parent->nextlevel != current) current = current->parent;
current = current->parent;
cout << "已返回至上一级目录:" << endl;
printcurrent();
}
void get(SystemNode *subtree,string str)
{
if (subtree)
{
if (subtree->data1.dname.find(str) != subtree->data1.dname.npos)
cout << "磁盘 " << subtree->data1.dname << " 总大小:" << subtree->data1.dsize << "M" << " 可用空间:" << subtree->data1.unusedspace << "M" << endl;
else if (subtree->data2.cname.find(str) != subtree->data2.cname.npos)
cout << "文件夹 " << subtree->data2.cname << " 修改日期:" << subtree->data2.savetime << " 大小:" << subtree->data2.csize << "M" << " 对象数:" << subtree->data2.number << endl;
else if (subtree->data3.fname.find(str) != subtree->data3.fname.npos)
cout << "文件 " << subtree->data3.fname << " 类型:" << subtree->data3.type << " 创建时间:" << subtree->data3.createtime << " 大小:" << subtree->data3.fsize << "M" << endl;
get(subtree->nextlevel, str);
get(subtree->equallevel, str);
}
}
void manage::search()
{
cout << "请输入您要查找的目录/文件名关键字:";
string s;
cin >> s;
cout << "模糊查找结果为:" << endl;
get(root,s);
}
void manage::deletesystem()
{
root = NULL;
current = NULL;
}
6、主函数:
void main()
{
manage snoopy;
int n;
cout << "欢迎使用Snoopy的资源管理器!" << endl;
cout << endl;
while (1)
{
cout << "*********************************" << endl;
cout << "1、新建磁盘" << endl;
cout << "2、删除磁盘" << endl;
cout << "3、选定磁盘" << endl;
cout << "4、在当前选择目录下新建目录" << endl;
cout << "5、在当前选择目录下删除目录" << endl;
cout << "6、在当前选择目录下选定文件夹" << endl;
cout << "7、在当前选择目录下新建文件" << endl;
cout << "8、在当前选择目录下删除文件" << endl;
cout << "9、输出当前目录下文件及文件夹信息" << endl;
cout << "10、回上一级" << endl;
cout << "11、查找目录/文件信息" << endl;
cout << "12、退出系统" << endl;
cout << "*********************************" << endl;
cout << "请选择您希望执行的操作:";
cin >> n;
if (n == 1) snoopy.createdisk();
else if (n == 2) snoopy.deletedisk();
else if (n == 3) snoopy.choosedisk();
else if (n == 4) snoopy.createcatalog();
else if (n == 5) snoopy.deletecatalog();
else if (n == 6) snoopy.choosecatalog();
else if (n == 7) snoopy.createfile();
else if (n == 8) snoopy.deletefile();
else if (n == 9) snoopy.printcurrent();
else if (n == 10) snoopy.gobacklast();
else if (n == 11) snoopy.search();
else if (n == 12) break;
cout << endl;
}
cout << endl;
cout << "欢迎您再次使用!" << endl;
cout << endl;
system("pause");
}
7、函数的调用关系图反映程序层次结构
四、测试实例
结论:测试结果正确。