3 文件目录管理与显示
1、题目的内容和要求
给出目录和文件信息,要求编程实现将其排列成一棵有一定缩进的树。
(1)设计文件和目录信息树的存储结构。
(2)从文件或键盘输入目录和文件信息,输入格式采用绝对路径法,即:
\A
\A\AA1
\A\AA1\aa1.doc
…
创建时要检查同一路径下不能有同名的目录或文件名。
(3)设计文件和目录信息树的输出格式(以凹入表的形式显示)。
(4)查找指定目录和文件。
(5)添加新目录或新文件。
(6)删除指定目录或文件,子目录能够被删除的前提是其为空,既不包含任何子目录
和文件;根目录不能删除。
(7)扩充目录或文件信息,如创建时间、读写权限、文件长度或子目录包含的子目录
和文件数等。
(8)对同一层次下的子目录或文件按创建时间有序输出。
选做内容:
(1)如何实现相对路径表示法。
(2)通配符的使用。如用“?”代表任意一个字符,用“*”表示任意多个多个任意字
符。
2、设计
2.1 设计思想
(1)数据结构设计:本体由于要对文件目录的处理,在一个文件中可以存放多个文件,
所以用树,并且用孩子兄弟表示法,表示该树。
(2)算法设计:当在该目录下添加,查找,删除子目录时,相当于在该目录下对其孩
子结点的处理,根据树建立和结点的孩子兄弟结点的处理来实现。
2.2 设计表示
建立空树
调用函数 TreeInitiate(SibTree *t)
插入根结点
调用函数 insertRoot( )
插入孩子结点
调用函数 insertChild(
)
继续添加文件
调用 add()
删除文件
调用 Delete()
查找文件
调用 check( )
输出文件目录
调用 out()
2.3 详细设计
编写树的建立和孩子结点的添加、删除、搜索等函数是比较简单的,关键在函数中怎么
去判断是给其插入孩子结点还是兄弟结点,在删除时还要判断该目录是否有子目录或者子文
件……这些都要在写程序时考虑进去,我认为这个题的难点还是在输出上,因为要按照题目
要求,以凹入法输出,在输出函数中就要想到用递归法来处理该问题。
3、调试
在写的过程中,没写一个函数都进行一次调试操作,以验证函数的正确性,在写完后,曾遇
到过这样的情况:给一个结点的兄弟插入孩子结点时,出现了错误插入,变成了给该结点插
入孩子结点,经过一步步的调试发现少一个判断过程,来判断这个结点是不是要插入的目的
结点,通过修改问题被解决。
4、用户手册
此程序在 VC 下运行,在运行时要按照每一步的提示的规格去进行操作
5、测试数据和结果截图
(1)初始时运行如图
(2)进行添加操作,以输入 0 结束
(3)进行查找操作
(4)进行删除操作
如果有子目录则不能删除或子文件
没有子目录或子文件时
(5)进行输出操作
(6)退出时输入 5 即可退出
6、源程序清单
(1)测试源文件 test.cpp
#include
#include
#include
#include
#include
using namespace std;
#include "Sibtree.h"
void add(SibTree *t1)
{
printf("输入目录文件信息以输入 0 结束:\n");
SibTreeNode *r, *r1,*r2;
char ifm[1000]={'\0'},name1[50],name2[50];
char *str;
int i,j,n;
while(1)
{
cin>>ifm;
str=ifm;
if(*str=='0')break;
r=t1->root;
if (r==NULL)
{
for (i=0,str+=1;*str!='\\'&&*str!='\0';str++,i++)
{
name1[i]=*str;
}
name1[i]='\0';
if(*str=='\0')insertRoot(t1,name1);
else
printf("%s 的路径不存在,不能添加\n",name1);
}
else
{
{
for (i=0,str+=1;*str!='\\'&&*str!='\0';str++,i++)
name1[i]=*str;
}
name1[i]='\0';
if(search(t1,name1)==0&&*str=='\0')
{
insertnextSibing(t1,r,name1);
}
if(search(t1,name1)==0&&*str!='\0')printf("%s 的路径不存在,不能添加\n",name1);
r1=LevelOrderTraverse(t1->root,name1);
while(r1!=NULL)
{
if(*str=='\0')break;
for (i=0,str+=1;*str!='\\'&&*str!='\0';str++,i++)
{
name2[i]=*str;
}
name2[i]='\0';
if(*str=='\0')
{
if(insertChild(t1,r1,name2)){break;}
}
else
{
n=children(r1);
for(j=1;j<=n;j++)
{
if(strcmp(child(r1,j)->data,name2)==0)break;
}
if(j<=n)r2=child(r1,j);
else r2=NULL;
if(r2==NULL)printf("%s 的路径不存在,不能添加\n",name2);
}
n=children(r1);
for(j=1;j<=n;j++)
{
if(strcmp(child(r1,j)->data,name2)==0)break;
}
if(j<=n)r1=child(r1,j);
else r1=NULL;
}
}
}
}
void check(SibTree *t)
{
SibTreeNode *r;
printf("输入要查找的文件名:");
char name[50];
cin>>name;
r=LevelOrderTraverse(t->root,name);
if(r==NULL)printf("没有此文件\n");
else
{
printf("此文件找到,创建时间为:");
printf("%d/%d/%d %d:%d:%d",r->year,r->month,r->day,r->hour,r->minute,r->second);
printf("\t 子目录个数为:");
printf("%d\n",children(r));
}
}
void Delete(SibTree *t)
{
SibTreeNode *r,*p,*kid;
printf("输入要删除的文件名:");
char name[50];
cin>>name;
r=LevelOrderTraverse(t->root,name);
if(r==NULL)printf("没有此文件!\n");
else
{
if(r->firstChild!=NULL)printf("有子文件不能删除!\n");
else
{
p=r->parent;
kid=p->firstChild;
if(strcmp(kid->data,r->data)==0)p->firstChild=kid->nextSibling;
else
{
while(strcmp(kid->nextSibling->data,r->data))kid=kid->nextSibling;
kid->nextSibling=kid->nextSibling->nextSibling;
}
printf("已删除!\n");
}
}
}
void out(SibTree *t)
{
printf("输出文件目录的信息:\n");
printf("root:\n");
printf("%s",toString(t).c_str());
}
void main( )
{
SibTree t1;
int k;
TreeInitiate(&t1);
while(1)
{
文件管理
\t\n");
*************对照号码输入你要进行的操作*************\n");
printf("\n");
printf("\t
printf("\t********************************************************\t\n");
printf("\t
printf("\t
printf("\t
printf("\t
printf("\t
printf("\t
printf("输入你想进行的操作号码:");
scanf("%d",&k);
if(k==5)break;
switch (k)
{
case 1: add(&t1);
1 ——>添加
2 ——>查找
3 ——>删除
4 ——>输出
5 ——>退出
\n");
\n");
\n");
\n");
\n");
break;
case 2: check(&t1);
break;
case 3: Delete(&t1);
break;
case 4: out(&t1);
break;
default:
printf("输入号码错误!\n");
}
}
}
(2)包含的头文件 Sibtree.h
#include
SYSTEMTIME sys;
typedef struct SibTreeNode
{
char data[50];
int valid;
int year;
int month;
int day;
int hour;
int minute;
int second;
int sonmulu;
int sonfile;
struct SibTreeNode * parent;
struct SibTreeNode *firstChild;
struct SibTreeNode *nextSibling;
}SibTreeNode;
typedef struct
{
SibTreeNode *root;
int size;
}SibTree;
typedef SibTreeNode *QueueDataType;
#include "SeqCQueue.h"
int IsTreeEmpty(SibTree *t)
{
return t->size == 0;
}
int isValidNode(SibTreeNode *p)
{
if(p)
return p->valid;
else return 0;
}
//创建一个空树
void TreeInitiate(SibTree *t)
{
t->root = NULL;
t->size = 0;
}
//创建结点
SibTreeNode * newSibTreeNode(char x[50])
{
GetLocalTime(&sys);
SibTreeNode *p=(SibTreeNode *)malloc(sizeof(SibTreeNode));
strcpy(p->data,x);
p->valid = true;
p->year = sys.wYear;
p->month = sys.wMonth;
p->day = sys.wDay;
p->hour = sys.wHour;
p->minute = sys.wMinute;
p->second = sys.wSecond;
p->sonmulu=5;
p->sonfile=1;
p->parent = NULL;
p->firstChild = NULL;
p->nextSibling = NULL;
return
//扩充的信息,限制子目录的个数
//限制子文件的个数
p;
}
//创建包含一个结点的树
void onenodeSibTree(SibTree *t,char x[50])
{
t->root = newSibTreeNode(x);
strcpy(t->root->data,x);
t->size = 1;
}