#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <stdlib.h>
#include<time.h>
#include <string.h>
#define MAX_FILE 10 //最大文件个数
#define FILE 1 //结点代表为文件
#define FOLDER 0 //结点代表为文件夹
typedef struct FileNode {
char name[20]; //文件名称
char path[200]; //文件路径
time_t create_t; //创建时间
int status; //文件属性
struct FileNode *child, *brother; //孩子节点和兄弟节点
}FileNode, *File; // 结点别名,指向结点的指针别名
File root; //根文件
File current; //当前文件
File p; //文件的指针
File path; //待使用的工具结构体
File T;
int type; //新建文件类型
int symbol;
char com[10];
char fircom[10]; //第一级命令
char seccom[10]; //第二级命令
//系统初始化
void Init() {
root = (FileNode *)malloc(sizeof(FileNode));
current = (FileNode *)malloc(sizeof(FileNode));
path = (FileNode *)malloc(sizeof(FileNode));
T = (FileNode *)malloc(sizeof(FileNode)); //root、current、path、T申请内存空间。
strcpy(root->name, "ROOT");
strcpy(root->path, "ROOT");//初始化ROOT根目录路径
root->create_t = time(NULL);
root->status = 0;
root->child = NULL;
root->brother = NULL;
}
//变量直接赋值函数
void Add(File *a, File *b)
{
(*a)->create_t = (*b)->create_t;
(*a)->child = (*b)->child;
strcpy((*a)->name, (*b)->name);
(*a)->brother = (*b)->brother;
(*a)->status = (*b)->status;
strcpy((*a)->path, (*b)->path);
}
//查找目标文件工具
void Research(File F)
{ //遍历当前节点的所有子孙节点找到目标节点
if (F == NULL) //判断当前结点是否为NULL
return;
if (strcmp(F->path, path->path) == 0)//判断是否为目标文件
{
Add(¤t, &F);
p = F; //把当前文件改为目标文件
symbol = 0; //设置寻找结果标志
}
if (symbol == 1)
{
Research(F->child); //递归函数
Research(F->brother);
}
return;
}
//文件|文件夹切换
void Cd()
{
if (strcmp(seccom, "\") == 0) //返回根文件
{
if (strcmp(p->path, "ROOT") == 0) //如果当前文件在Root不做反应
{
return;
}
p = root; //在任意路径下切换回根路径 ROOT
Add(¤t, &p);
}
else if (strcmp(seccom, "..") == 0) //切换到当前路径的上级文件夹
{
if (strcmp(current->path, "ROOT") == 0) //如果当前文件在Root不做反应
{
return;
}
else
{
strcpy(seccom, current->path); //当前文件不在根文件
int a = strlen(seccom); //从当前文件的path字符串中截取双亲文件的path,然后从根文件向下寻找
char * find = strrchr(seccom, '\\');
int b = strlen(find);
int c = a - b;
char d[100] = "0";
strncpy(d, seccom, c);
strcpy(path->path, d); //得到双亲文件的path
symbol = 1; //初始化寻找结果标志
Research(root); //从root开始查找
}
}
else
{
symbol = 1; //初始化寻找结果标志
Add(&T, ¤t);
Add(&path, ¤t);
strcat(path->path, "\");
strcat(path->path, seccom);
Research(T); //查找目标文件工具
if (symbol == 1)
printf("路径不存在或者错误!!!\n");
}
}
//遍历文件
void Traverse(File F)
{
printf("%s", F->name); //输出名称
if (F->status == 1) //输出文件类型
printf(" FILE ");
else
printf(" FOLDER ");
time(&F->create_t); //输出时间
printf("创建日期:%s", asctime(gmtime(&F->create_t)));
if (F->brother != NULL)
Traverse(F->brother);
return;
}
//列出当前路径下的全部文件夹和文件
void Dir()
{
if (p->child != NULL) //是否有子节点且不是文件
{
Traverse(p->child);
}
}
//新建文件夹\文件
void AddFile(File *New)
{
char *a = NULL;
a = (char*)malloc(100);
strcpy(a, current->path); //制作新文件的path
strcat(a, "\");
strcat(a, seccom);
*New = (File)malloc(sizeof(FileNode));
//New=new FileNode;
strcpy((*New)->name, seccom); //新建文件的name
strcpy((*New)->path, a); //新建文件的path
(*New)->create_t = time(NULL); //新建文件的time
(*New)->status = type; //新建文件的类型
(*New)->child = NULL;
(*New)->brother = NULL;
}
void NewFile()
{
if (p->status == 1) //判断文件类型
{
printf("这是一个文件!\n");
return;
}
if (p->child != NULL) //判断新建的文件是否存在
{
if (strcmp(p->child->name, seccom) == 0) //判断新建的第一个子文件是否和新建文件同名
{
printf("文件|文件夹已存在!\n");
return;
}
p = p->child; //把当前文件改为目标文件
while (!((p->brother == NULL) || (strcmp(p->brother->name, seccom) == 0))) //判断当前文件的下一个兄弟文件是否和新建文件同名
p = p->brother;
if (p->brother != NULL) //判断上一个结束原因
{
Add(¤t, &p);
strcpy(seccom, ".."); //如果存在同名文件,返回主函数,并且调整当前文件指针指向
Cd();
printf("文件|文件夹已存在!!\n");
return;
}
else
{
Add(¤t, &p);
strcpy(com, seccom);
strcpy(seccom, ".."); //不存在同名文件夹,调整当前文件指针指向
Cd();
strcpy(seccom, com);
}
}
if (p->child != NULL) //判断是否有子文件
{
p = p->child;
while (p->brother != NULL)
p = p->brother;
AddFile(&(p->brother));
Add(¤t, &p);
strcpy(seccom, "..");
Cd();
}
else
{
AddFile(&(p->child));
Add(¤t, &p);
printf("文件|文件夹");
printf("创建成功\n");
}
}
void Delete() //删除文件\文件夹
{
if (strcmp(p->child->name, seccom) == 0) //判断子文件是否为待删除文件
{
p->child = p->child->brother;
return;
}
p = p->child; //调整当前文件指针指向
while (!((p->brother == NULL) || (strcmp(p->brother->name, seccom) == 0)))//判断当前文件的下一个兄弟文件是否为待删除命令
p = p->brother; //调整当前文件指针指向
if (p->brother == NULL)
{
Add(¤t, &p);
strcpy(seccom, "..");
Cd();
return;
}
p->brother = p->brother->brother;
Add(¤t, &p);
strcpy(seccom, "..");
Cd(); //删除之后返回到双亲文件
}
//退出系统
void Exit()
{
printf("谢谢使用!\n");
exit(0);
}
int main()
{
Init(); //系统初始化
printf("*****欢迎使用本系统****\n");
printf("使用说明:\n");
printf("1.在当前路径下新建文件夹:md\n");
printf("2.在当前路径下新建文件:mf\n");
printf("3.在任意路径下切换回根路径 ROOT:cd \\\n");
printf("4.列出当前路径下的全部文件夹和文件:dir\n");
printf("5.切换到当前路径下的某文件夹:cd 文件夹|文件\n");
printf("6.切换到当前路径的上级文件夹:cd ..\n");
printf("7.删除当前路径下的某文件或文件夹(及其下所有文件夹及文件):del\n");
printf("8.退出系统:exit\n");
Add(¤t, &root);
p = root;
while (1)
{
printf("%s> ", current->path); //输出当前位置
scanf("%s", fircom);//cin>>fircom; //获得第一级命令
if (!strcmp(fircom, "exit"))
{
Exit(); //退出系统
}
else if (!strcmp(fircom, "dir"))
{
Dir(); //列出当前文件夹的全部文件和详细信息
fflush(stdin);//cin.sync();
}
else if (!strcmp(fircom, "cd") || !strcmp(fircom, "md") || !strcmp(fircom, "mf") || !strcmp(fircom, "del"))
{
scanf("%s", seccom);//cin>>seccom;
if (!strcmp(fircom, "cd")) //切换到当前路径下的某文件夹
{
Cd();
}
else if (!strcmp(fircom, "md")) //新建文件夹
{
type = 0;
NewFile();
}
else if (!strcmp(fircom, "mf")) //新建文件
{
type = 1;
NewFile();
}
else if (!strcmp(fircom, "del")) //删除文件\文件夹
{
Delete();
}
}
else
{
fflush(stdin); //清除缓冲区未读取信息
}
}
return 0;
}