📄 filesys.c
字号:
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#define FILENAME_LEN 21
#define INPUT_LEN 81
#define COMMAND_LEN 11
//结点结构
struct FileNode
{
char filename[FILENAME_LEN];//文件名/目录名
int isdir;//目录文件识别标志
int i_nlink;//文件的链接数
int adr;//文件的地址
struct FileNode *parent, *child;//指向父亲的指针和指向左孩子的指针
struct FileNode *sibling_prev, *sibling_next;//指向前一个兄弟的指针和指向
//后一个兄弟的指针.
};
void Init();//初始化文件树
int ParseCommand();//接受输入的命令并把其分解成操作名和路径文件名
void ExecuteCommand();//执行命令
int cdComd();//处理cd命令
int editComd();//处理edit命令
int delComd();//处理del命令
int rdComd();//处理rd命令
int dirComd();//处理dir命令
int mdComd();//处理md命令
int FindPath(char *ph);//寻找参数ph所指向的路径
//从参数Para2中找到要建立或删除的文件、目录名,并把指针指向其父亲结点
int FindFilename(char Para2[]);
struct FileNode* CreateFileNode(char filename[],int isdir,int i_nlink);//创建结点
int GetInput(char* buffer,unsigned int buffer_len);//获取输入
int CheckCommand();//命令检查
int GetDir(int begin,char* path,char* curDir);//获取路径
void Trim(char* str);
struct FileNode * cp, *tp, *root,*upper;
char path[INPUT_LEN-COMMAND_LEN];//记录当前走过的路径
char curpath[INPUT_LEN-COMMAND_LEN],Para1[COMMAND_LEN],
Para2[INPUT_LEN-COMMAND_LEN],tmppath[INPUT_LEN-COMMAND_LEN];
char filename[FILENAME_LEN],dirname[FILENAME_LEN],tmp;
int i,j;
//主函数
int main()
{
Init();//初始化文件树
while(1)
{
if(ParseCommand())//分解命令
ExecuteCommand();//执行命令
}
}
//执行命令子函数
void ExecuteCommand()
{
int sign;
//根据参数Para1调用相应的功能处理模块
if(strcmp(Para1,"cd")==0)
sign=cdComd(); //cd命令
else if(strcmp(Para1,"edit")==0)
sign=editComd(); //edit命令
else if(strcmp(Para1,"del")==0)
sign=delComd(); //del命令
else if(strcmp(Para1,"dir")==0)
sign=dirComd(); //dir命令
else if(strcmp(Para1,"md")==0)
sign=mdComd(); //md命令
else if(strcmp(Para1,"rd")==0)
sign=rdComd(); //rd命令
else if(strcmp(Para1,"exit")==0)
exit(0); //exit命令
else
printf("命令错误,请重试\n"); //命令输入不正确,报错
}
//创建结点
struct FileNode* CreateFileNode(char filename[],int isdir,int i_nlink)
{
//申请结点空间
struct FileNode* node=(struct FileNode*)malloc(sizeof(struct FileNode));
//相应内容赋初值
strcpy(node->filename,filename);
node->isdir=isdir;
node->i_nlink=i_nlink;
node->parent=NULL;
node->child=NULL;
node->sibling_prev=NULL;
node->sibling_next=NULL;
return node;
}
//初始化文件树
void Init()
{
struct FileNode *binNode,*usrNode,
*unixNode,*etcNode,*libNode,*userNode,
*binNode2,*liuNode,*sunNode,*ftiNode;
strcpy(path,"/"); //根目录写入当前路径
//创建文件树的结点
binNode=CreateFileNode("bin",1,0);
usrNode=CreateFileNode("usr",1,0);
unixNode=CreateFileNode("unix",0,0);
etcNode=CreateFileNode("etc",1,0);
libNode=CreateFileNode("lib",1,0);
userNode=CreateFileNode("user",1,0);
binNode2=CreateFileNode("bin",1,0);
liuNode=CreateFileNode("liu",1,0);
sunNode=CreateFileNode("sun",1,0);
ftiNode=CreateFileNode("fti",1,0);
cp=tp=root=CreateFileNode("/",1,0);
//结点相应内容赋值
root->parent=NULL;
root->child=binNode;
root->sibling_prev=root->sibling_next=NULL;
binNode->parent=root;
binNode->child=NULL;
binNode->sibling_prev=NULL;
binNode->sibling_next=usrNode;
usrNode->parent=NULL;
usrNode->child=libNode;
usrNode->sibling_prev=binNode;
usrNode->sibling_next=unixNode;
unixNode->parent=NULL;
unixNode->child=NULL;
unixNode->sibling_prev=usrNode;
unixNode->sibling_next=etcNode;
etcNode->parent=NULL;
etcNode->child=NULL;
etcNode->sibling_prev=unixNode;
etcNode->sibling_next=NULL;
libNode->parent=usrNode;
libNode->child=liuNode;
libNode->sibling_prev=NULL;
libNode->sibling_next=userNode;
userNode->parent=NULL;
userNode->child=NULL;
userNode->sibling_prev=libNode;
userNode->sibling_next=binNode2;
binNode2->parent=NULL;
binNode2->child=NULL;
binNode2->sibling_prev=userNode;
binNode2->sibling_next=NULL;
liuNode->parent=libNode;
liuNode->child=NULL;
liuNode->sibling_prev=NULL;
liuNode->sibling_next=sunNode;
sunNode->parent=NULL;
sunNode->child=NULL;
sunNode->sibling_prev=liuNode;
sunNode->sibling_next=ftiNode;
ftiNode->parent=NULL;
ftiNode->child=NULL;
ftiNode->sibling_prev=sunNode;
ftiNode->sibling_next=NULL;
}
//获取文件或目录名,并把指针指向其父亲结点
int FindFilename(char Para2[])
{
i=strlen(Para2)-1;
j=0;
while(Para2[i]!='/'&& i>=0)
{
filename[j]=Para2[i];
i--; j++;
}
filename[j]='\0';//获得逆序的文件或目录名,存入filename中
if(i<0) Para2[i+1]='\0';
else Para2[i]='\0';
j--;
//filename逆转,获得正确的文件或目录名
for(i=0;i<strlen(filename)/2;i++,j--)
{
tmp=filename[i];
filename[i]=filename[j];
filename[j]=tmp;
}
//查找路径
if(strlen(Para2)>0)
{
int sign=FindPath(Para2);
if(sign==0) return 0;
}
return 1;
}
//缓冲区安全输入子函数
//如果输入超过buffer_len,则截取前buffer_len-1长度的输入,
//buffer_len处字符用'/0'代替
int GetInput(char* buffer,unsigned int buffer_len)
{
int count=0;
while(count<buffer_len)
{
if((buffer[count]=getchar())==10)
{
buffer[count]='\0';
return count;
}
count++;
}
while(getchar()!=10);
buffer[buffer_len-1]='\0';
return -1;
}
//分解命令子函数
int ParseCommand()
{
char Inputs[INPUT_LEN];
int i=0,j=0,k=0,ch;
printf("%s>",path);
//获取输入
if(GetInput(Inputs,INPUT_LEN)==-1)
{
printf("输入行太长。\n");
return 0;
}
Para1[0]=Para2[0]='\0';
//获取参数Para1,即操作名
while(Inputs[i]!=' '&&Inputs[i]!='\0' && i<COMMAND_LEN-1)
{
Para1[i]=Inputs[i];
i++;
}//while
Para1[i]='\0';
//输入命令太长
if(i==(COMMAND_LEN-1))return 1;
//获取参数2,即路径文件名
if(Inputs[i]!='\0')
{
while(Inputs[i]==' ' && i<INPUT_LEN-1) i++;
j=0;
while(Inputs[i]!='\0' && i<INPUT_LEN-1)
{
Para2[j]=Inputs[i];
i++; j++;
}
Para2[j]='\0';
}
Trim(Para1);
Trim(Para2);
//将操作名全部转换成小写字母
for(k=0;k<strlen(Para1);k++)
{
ch=tolower((int)Para1[k]);
Para1[k]=ch;
}
return 1;
}
//cd功能处理子函数
int cdComd()
{
if(!CheckCommand())//命令检查
return 0;
if(strcmp(Para2,"..")==0)
{ //对cd ..命令的处理
int i;
while(cp->sibling_prev)
cp=cp->sibling_prev;//找到这一层最左边的结点
if(cp->parent)
{
cp=cp->parent;//找到父亲结点
}
else
{
return 0;
}
//对当前路径进行相应处理
i=strlen(path);
while(path[i]!='/'&& i>0) i--;
if(i!=0)
path[i]='\0';
else
path[i+1]='\0';
}
else
{
FindPath(Para2);//查找路径
}
return 1;
}
//命令格式处理子函数
void Trim(char* str)
{
int begin,end;
char* tmp;
begin=0;
end=strlen(str);
//找到字符串第一个非空格的位置
while(str[begin]==' ' && str[begin]!='\0')begin++;
//去除字符串尾部空格
while(str[--end]==' ');
str[end+1]='\0';
//除去空格
if(begin<end)
{
tmp=(char*)malloc((sizeof(char))*(end-begin+2));
strcpy(tmp,&str[begin]);
strcpy(str,tmp);
free(tmp);
}
}
//获取当前目录名子函数
int GetDir(int begin,char* path,char* curDir)
{
int i=0;
int len=strlen(path);
while(!((path[begin]=='\\' )|| (path[begin]=='/'))&&begin<len)
{
curDir[i++]=path[begin++];
}
curDir[i]='\0';
Trim(curDir);
return begin+1;
}
//查找路径子函数
int FindPath(char *ph)
{
struct FileNode *tp,*temp;
char oldpath[INPUT_LEN-COMMAND_LEN];
int i=0;
int sign=1;
if(strcmp(ph,"/")==0)
{ //ph是根目录
cp=root;
strcpy(path,"/");
return 1;
}
temp=cp;
strcpy(oldpath,path);//保存原路径和指针
if(ph[0]=='/')
{ //指针指向根目录的左孩子
cp=root->child;
i++;//滤过'/'
strcpy(path,"/");
}
else
{
if(cp!=NULL && cp!=root )
strcat(path,"/");
if(cp && cp->child)
{
if(cp->isdir)
cp=cp->child; //指针指向当前目录的左孩子
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -