操作系统实验

操作系统实验1 动态优先权

//实验1-动态优先权(队列实现) 
#define OK 1 
#define OVERFLOW -2 
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define null 0
#include<stdlib.h>
#include<iomanip>
#include<iostream>
using namespace std;
enum STATE{
	ready=1, 
	running=2,
	block=3,
	finish=4
};
typedef int Status;
typedef struct process{
	int id;
	int priority;
	int cputime;
	int alltime;
	int startblock;
	int blocktime;
	enum STATE state;
	struct process *next;
}process,*queueptr;
typedef process QElemType;
struct LinkQueue
{
	queueptr front,rear;
	int size;
};
int coutpros(LinkQueue &q,LinkQueue &blockq,LinkQueue &finishq,int &t)
{ //输出当前各进程的情况 
	queueptr p;
	cout<<setw(12)<<"id ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->id;
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->id; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->id; 
	}
	cout<<"\n"<<setw(12)<<"priority ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->priority;
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->priority; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->priority; 
	}
	cout<<"\n"<<setw(12)<<"cputime ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->cputime;
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->cputime; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->cputime; 
	}
	cout<<"\n"<<setw(12)<<"alltime ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->alltime;
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->alltime; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->alltime; 
	}
	cout<<"\n"<<setw(12)<<"startblock ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->startblock;
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->startblock; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->startblock; 
	}
	cout<<"\n"<<setw(12)<<"blocktime ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->blocktime;
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->blocktime; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<p->blocktime; 
	}
	cout<<"\n"<<setw(12)<<"state ";
	for(p=q.front->next;p!=null;p=p->next)
	{
		if(p->state==1) cout<<setw(8)<<"ready"; 
		if(p->state==2) cout<<setw(10)<<"running";
	}
	for(p=blockq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<"block"; 
	}
	for(p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(8)<<"finish"; 
	}
	cout<<"\n\n\n";
	return 0;	
}
Status InitQueue(LinkQueue &Q)
{ //构造一个空队列Q
	Q.front=Q.rear=(queueptr)malloc(sizeof(QElemType));
	if(!Q.front)  //存储分配失败 
		exit(OVERFLOW);
	Q.front->next=Q.rear->next=NULL;
	Q.size=0;
    return OK;
}
Status EnQueue(LinkQueue &Q,QElemType &pro)
{ //入队,插入结点pro为Q的新的队尾元素
	queueptr p;
	p=(queueptr)malloc(sizeof(QElemType));
   	if(!p)  //存储分配失败
		exit(OVERFLOW);
   	*p=pro;
   	p->next=NULL;
   	Q.rear->next=p;
   	Q.rear=p;
   	Q.size++;
   	return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &pro)
{ //出队,删除Q的队头元素并赋值给pro 
	queueptr p;
   	if(Q.front==Q.rear) //队列空,返回ERROR 
		return ERROR;
   	p=Q.front->next;
   	pro=*p;
   	if(Q.rear==p)
   	{
   		Q.rear=Q.front;
	}
	Q.front->next=p->next;
   	free(p);
   	Q.size--;
   	return OK;
}
int main()
{
	process pro0={0,9,0,3,2,3,ready,null},
			pro1={1,38,0,3,-1,0,ready,null},
			pro2={2,30,0,6,-1,0,ready,null},
			pro3={3,29,0,3,-1,0,ready,null},
			pro4={4,0,0,4,-1,0,ready,null};
	process pro;
	LinkQueue q;
	LinkQueue blockq;
	LinkQueue finishq;
	InitQueue(q);
	InitQueue(blockq);
	InitQueue(finishq);
	EnQueue(q,pro0);
	EnQueue(q,pro1);
	EnQueue(q,pro2);
	EnQueue(q,pro3);
	EnQueue(q,pro4);
	int t=0;
	while(q.front!=q.rear)
	{
		queueptr p,s,b;
		while(1)
		{
			t++;
			for(int i=0;i<q.size-1;i++)
			{
				p=q.front->next;
				s=q.front;
				for(int j=1;j<q.size;j++)
				{
					if(p->priority<(p->next)->priority)
					{
						s->next=p->next;
						p->next=p->next->next;
						s->next->next=p;
					}
					s=s->next;
					p=s->next;
				}
				if(i==q.size-2)
				{
					q.rear=p;
				}
			}
			//ready(priority加1)
			p=q.front->next;
			p=p->next;
			for(int i=1;i<q.size;i++)
			{
				p->priority+=1;
				p->state=ready;
				p=p->next;	
			} 
			//block 
			b=blockq.front->next;
			for(int i=0;i<blockq.size;i++)
			{
				b->blocktime-=1;
				if(b->blocktime==0)
				{
					b->state=ready;
					DeQueue(blockq,pro);
					EnQueue(q,pro);
					break;
				}
				b=b->next;
			} 
			//running 
			p=q.front->next;
			p->state=running;
			p->priority-=3;
			p->cputime+=1;
			p->alltime-=1;
			cout<<"Current time slice:"<<t<<endl;
			cout<<"the process currently executing:"<<p->id<<endl;
			coutpros(q,blockq,finishq,t);
			if(p->alltime==0)
			{ //该进程执行结束 
				p->state=finish; 
				DeQueue(q,pro);
				EnQueue(finishq,pro);
				break;
			}
			if(p->startblock!=-1)
			{
				p->startblock-=1;
				if(p->startblock==0)
				{ //进程挂到阻塞队列 
					p->state=block;
					DeQueue(q,pro);
					EnQueue(blockq,pro);
				}
			}
		}
	} 
	cout<<"-----------------------------------------------"<<endl;
	cout<<"The completion order of the process :";
	for(queueptr p=finishq.front->next;p!=null;p=p->next)
	{
		cout<<setw(4)<<p->id; 
	}
	cout<<"\n-----------------------------------------------\n";
	return 0;
}

操作系统实验2 内存分配

//实验2-内存分配(双向链表实现) 
#define OVERFLOW -2
#define null 0
#include<stdlib.h>
#include<iostream>
using namespace std;
enum STATE{
	Free=1, 
	Occupy=2
};
typedef struct space{
	int id;
	int address;
	int size;
	enum STATE state;
}space,*spaceptr;
typedef space QElemType;
typedef struct Node pNode;
typedef struct Node
{
	QElemType space;
	pNode *prev, *next;
}Node,*ListPtr;
int initDL(ListPtr &head)
{
	head=(pNode* )malloc(sizeof(pNode));
	if(head==null)  //存储分配失败 
		exit(OVERFLOW);
	head->prev=null;
	head->next=null;
	head->space.id=0;
	head->space.address=null;
	head->space.size=0;
	head->space.state=Free;
	return 0;
}
int coutfl(ListPtr fl)
{//输出空闲链 
	pNode *q;
	for(q=fl;q!=null;q=q->next)
	{
		cout<<"空闲分区:始址="<<q->space.address<<"KB,大小="<<q->space.size<<"KB"<<endl; 
	}
	return 0;
}
int coutol(ListPtr ol)
{//输出占用链 
	pNode *q;
	for(q=ol;q!=null;q=q->next)
	{
		cout<<"已分配分区:作业号="<<q->space.id<<",始址="<<q->space.address<<"KB,大小="<<q->space.size<<"KB"<<endl; 
	}
	return 0;
}
int deleteDL(ListPtr &head,space s)
{
	pNode *p,*q;
	p->space=s;
	for(q=head;q!=null;q=q->next)
	{
		if(p->space.id==q->space.id)
		{
			q->prev->next=q->next;
			q->next->prev=q->prev;
			free(q); 
			break;
		}
	}
	return 0;
}
int alloc(space s,ListPtr &fl,ListPtr &ol)
{
	cout<<"分配内存:";
	cout<<"作业"<<s.id<<"申请"<<s.size<<"KB"<<endl;
	pNode *p,*q,*t;
	p=(pNode* )malloc(sizeof(pNode));
	p->space=s;
	for(q=fl;q!=null;q=q->next)
	{
		if(p->space.size<=q->space.size)
		{//能装下作业t当前申请的空间 
			p->space.address=q->space.address;
			p->space.state=Occupy;
			if(p->space.size==q->space.size)
			{
				deleteDL(fl,q->space);
			}
			else
			{
				q->space.address+=p->space.size;
				q->space.size-=p->space.size; 
			}
			break;
		} 
	}
	for(t=q=ol;q!=null;t=q,q=q->next)
	{//找该作业空间在占用链表中的位置 
		if(ol->space.size==0)
		{
			ol->space.id=p->space.id;
			ol->space.address=0;
			ol->space.size=p->space.size;
			ol->space.state=Occupy;
			break;
		}
		if(p->space.address<=q->space.address)
		{
			if(q==ol)
			{
				p->prev=null;
				p->next=q;
				q->prev=p;
				ol=p;
			}
			else
			{
				p->prev=q->prev;
				p->next=q;
				q->prev->next=p;
				q->prev=p;
			}
			break;
		} 
	}
	if(q==null)
	{
		t->next=p;
		p->prev=t;
		p->next=null;
	}
	coutfl(fl);
	coutol(ol);
	cout<<"\n";
	return 0;
}
int merge(ListPtr &head)
{//合并相邻接的空间(首次适应算法调用该函数) 
	pNode *p,*q;
	while(1)
	{
		int m=0;
		for(p=head;p->next!=null;p=p->next)
		{
			if(p->space.address+p->space.size==p->next->space.address)
			{
				p->space.size+=p->next->space.size;
				q=p->next;
				q->next->prev=p;
				p->next=q->next;
				free(q);
				m++;
			}
		}
		if(m==0)
		{
			break;
		}
	};
	return 0;
}
int merge_sort(ListPtr &head)
{//合并相邻接的空间并按空间块的大小排序(最佳适应算法调用该函数) 
	pNode *p,*q,*t;
	t=(pNode* )malloc(sizeof(pNode));
	while(1)
	{
		int e=0;
		for(p=head;p->next!=null;p=p->next)
		{
			if(p->space.address>=p->next->space.address)
			{
				t->space=p->next->space;
				p->next->space=p->space;
				p->space=t->space;
				e++;
			}
		}
		if(e==0)
		{
			break;
		}
	};
	while(1)
	{
		int m=0;
		for(p=head;p->next!=null;p=p->next)
		{
			if(p->space.address+p->space.size==p->next->space.address)
			{
				p->space.size+=p->next->space.size;
				q=p->next;
				q->next->prev=p;
				p->next=q->next;
				free(q);
				m++;
			}
		}
		if(m==0)
		{
			break;
		}
	};
	while(1)
	{
		int n=0;
		for(p=head;p->next!=null;p=p->next)
		{
			if(p->space.size>=p->next->space.size)
			{
				t->space=p->next->space;
				p->next->space=p->space;
				p->space=t->space;
				n++;
			}
		}
		if(n==0)
		{
			break;
		}
	};
	return 0;
}
int freet(space s,ListPtr &fl,ListPtr &ol,int (*algo)(ListPtr &head))
{
	pNode *p,*q,*t;
	cout<<"回收内存:";
	cout<<"作业"<<s.id<<"释放"<<s.size<<"KB" <<endl;
	p=(pNode* )malloc(sizeof(pNode));
	p->space=s;
	//从占用链中删去释放的内存 
	for(t=ol;t!=null;t=t->next)
	{
		if(p->space.id==t->space.id)
		{
			if(p->space.size>t->space.size)
			{//释放的空间大于实际占用的空间,非法! 
				exit(OVERFLOW); 
			}
			else
			{
				if(p->space.size==t->space.size)
				{
					if(t==ol)
					{
						p->space.address=t->space.address;
						t->next->prev=null;
						ol=t->next;
						free(t);
					}
					else
					{
						p->space.address=t->space.address;
						t->next->prev=t->prev;
						t->prev->next=t->next;
						free(t);	
					}
				}
				else
				{//释放的空间小于实际占用的空间
					s.address=t->space.address;
					t->space.address-=s.size;
					t->space.size-=p->space.size;
				}
			}
			break;
		}
	}
	//将释放的内存挂到空闲链中
	for(q=fl;q!=null;q=q->next)
	{
		if(p->space.address<=q->space.address)
		{
			if(q==fl)
			{
				p->next=q;
				q->prev=p;
				p->prev=null;
				fl=p;
			}
			else
			{
				p->prev=q->prev;
				p->next=q;
				q->prev->next=p;
				q->prev=p;
			}
			break;
		} 
	}
	algo(fl);
	coutfl(fl);
	coutol(ol);
	cout<<"\n";
	return 0;
}
int main()
{
	cout<<"*********************************"<<endl;
	cout<<"*           内存分配            *"<<endl;
	cout<<"*                               *"<<endl;
	cout<<"*        1.首次适应算法         *"<<endl;
	cout<<"*        2.最佳适应算法         *"<<endl;
	cout<<"*                               *"<<endl;
	cout<<"*********************************"<<endl;
	ListPtr fl,ol;
	ListPtr head;
	initDL(fl);
	initDL(ol);
	fl->space.id=0;
	fl->space.address=0;
	fl->space.size=640;
	fl->space.state=Free;
	int n;
	cin>>n;
	if(n==1)
	{
		system("cls");
		cout<<"\n***************首次适应算法****************\n\n";
		space s1={1,null,130,Free};
		alloc(s1,fl,ol);
		space s2={2,null,60,Free};
		alloc(s2,fl,ol);
		space s3={3,null,100,Free};
		alloc(s3,fl,ol);
		space s4={2,null,60,Free};
		freet(s4,fl,ol,merge);
		space s5={4,null,200,Free};
		alloc(s5,fl,ol);
		space s6={3,null,100,Free};
		freet(s6,fl,ol,merge);
		space s7={1,null,130,Free};
		freet(s7,fl,ol,merge);
		space s8={5,null,140,Free};
		alloc(s8,fl,ol);
		space s9={6,null,60,Free};
		alloc(s9,fl,ol);
		space s10={7,null,50,Free};
		alloc(s10,fl,ol);
		space s11={6,null,60,Free};
		freet(s11,fl,ol,merge);
	}
	if(n==2)
	{
		system("cls");
		cout<<"\n***************最佳适应算法****************\n\n";
		space s1={1,null,130,Free};
		alloc(s1,fl,ol);
		space s2={2,null,60,Free};
		alloc(s2,fl,ol);
		space s3={3,null,100,Free};
		alloc(s3,fl,ol);
		space s4={2,null,60,Free};
		freet(s4,fl,ol,merge_sort);
		space s5={4,null,200,Free};
		alloc(s5,fl,ol);
		space s6={3,null,100,Free};
		freet(s6,fl,ol,merge_sort);
		space s7={1,null,130,Free};
		freet(s7,fl,ol,merge_sort);
		space s8={5,null,140,Free};
		alloc(s8,fl,ol);
		space s9={6,null,60,Free};
		alloc(s9,fl,ol);
		space s10={7,null,50,Free};
		alloc(s10,fl,ol);
		space s11={6,null,60,Free};
		freet(s11,fl,ol,merge_sort);
	}
	return 0;
} 

操作系统实验3 请求调页

//实验3-请求调页 
#include<iomanip>
#include<stdlib.h>
#include<time.h>
#include<iostream>
using namespace std;
double cnt1,cnt2,cnt3;
double r1,r2,r3;
int a[4][2],b[320][2],c[320];
int f;
int opt()
{//opt算法 
	cnt1=0;
	f=0;
	int max[2];
	for(int t=0;t<4;t++)
	{
		a[t][1]=1;	
	} 
	for(int i=0;i<320;i++)
	{
		for(int t=0;t<4;t++)
		{
			if(a[t][1]<=0)
			{
				for(int m=i+1;m<320;m++)
				{
					if(a[t][0]==b[m][1])
					{
						a[t][1]=m-i;
						break;
					}	
				}	
			}	
		} 
		if(f<4)
		{
			int l=0;
			if(f>0)
			{
				for(int j=0;j<f;j++)
				{
					if(a[j][0]==b[i][1])
					{//内存中有该页
						l++;
						a[j][1]=0;
						break;
					}
				}	
			}
			if(l==0)
			{
				a[f][0]=b[i][1];
				for(int j=i+1;j<320;j++)
				{
					if(b[j][1]==b[i][1])
					{
						a[f][1]=j-i;
						break;
					}
				}
				f++;
			}
		}
		else
		{
			int e=0;
			for(int j=0;j<4;j++)
			{
				if(a[j][0]==b[i][1])
				{//内存中有该页
					e++;
					break;
				}
			}
			if(e==0)
			{
				cnt1++;
				cout<<"\nOPT第"<<cnt1<<"次缺页..."<<endl;
				cout<<"当前缺页的页号为:"<<b[i][1]<<endl;
				cout<<"当前内存的情况为:"<<endl;
				for(int j=0;j<4;j++)
				{
					cout<<setw(5)<<a[j][0];
				} 
				cout<<endl;
				for(int j=0;j<4;j++)
				{
					cout<<setw(5)<<a[j][1];
				} 
				cout<<endl;  
				max[1]=-10;
				for(int j=0;j<4;j++)
				{
					if(a[j][1]<0)
					{
						max[1]=a[j][1];
						max[0]=j;
						break;
					}
					else
					{
						if(a[j][1]>=max[1])
						{
							max[1]=a[j][1];
							max[0]=j;
						}
					}
				}
				a[max[0]][0]=b[i][1];
				for(int j=i+1;j<320;j++)
				{
					if(b[j][1]==b[i][1])
					{
						a[max[0]][1]=j-i;
						break;
					}
				}
			}	
		}
		for(int i=0;i<4;i++)
		{
			a[i][1]--;
		}
	}
	return 0;
}
int fifo()
{//先进先出FIFO算法 
	cnt2=0;
	f=0;
	int max[2];
	for(int i=0;i<320;i++)
	{
		if(f<4)
		{
			int l=0;
			if(f>0)
			{
				for(int j=0;j<f;j++)
				{
					if(a[j][0]==b[i][1])
					{//内存中有该页
						l++;
						break;
					}
				}	
			}
			if(l==0)
			{
				a[f][0]=b[i][1];
				a[f][1]=0;
				f++;
			}
		}
		else
		{
			int e=0;
			for(int j=0;j<4;j++)
			{
				if(a[j][0]==b[i][1])
				{//内存中有该页
					e++;
					break;
				}
			}
			if(e==0)
			{
				cnt2++;
				max[1]=0;
				cout<<"\nFIFO第"<<cnt2<<"次缺页..."<<endl;
				cout<<"当前缺页的页号为:"<<b[i][1]<<endl;
				cout<<"当前内存的情况为:"<<endl;
				for(int j=0;j<4;j++)
				{
					cout<<setw(5)<<a[j][0];
				} 
				cout<<endl;
				for(int j=0;j<4;j++)
				{
					cout<<setw(5)<<a[j][1];
				}
				cout<<endl; 
				for(int j=0;j<4;j++)
				{
					if(a[j][1]>=max[1])
					{
						max[1]=a[j][1];
						max[0]=j;
					}
				}
				a[max[0]][0]=b[i][1];
				a[max[0]][1]=0;
			}	
		}
		for(int i=0;i<4;i++)
		{
			a[i][1]++;
		}
	}
	return 0;
}
int lru()
{//最近最久未使用LRU算法 
	cnt3=0;
	f=0;
	int max[2];
	for(int i=0;i<320;i++)
	{
		if(f<4)
		{
			int l=0;
			if(f>0)
			{
				for(int j=0;j<f;j++)
				{
					if(a[j][0]==b[i][1])
					{//内存中有该页
						l++;
						a[j][1]=0;
						break;
					}
				}	
			}
			if(l==0)
			{
				a[f][0]=b[i][1];
				a[f][1]=0;
				f++;
			}
		}
		else
		{
			int e=0;
			for(int j=0;j<4;j++)
			{
				if(a[j][0]==b[i][1])
				{//内存中有该页
					e++;
					a[j][1]=0;
					break;
				}
			}
			if(e==0)
			{
				cnt3++;
				max[1]=0;
				cout<<"\nLRU第"<<cnt3<<"次缺页..."<<endl;
				cout<<"当前缺页的页号为:"<<b[i][1]<<endl;
				cout<<"当前内存的情况为:"<<endl;
				for(int j=0;j<4;j++)
				{
					cout<<setw(5)<<a[j][0];
				} 
				cout<<endl;
				for(int j=0;j<4;j++)
				{
					cout<<setw(5)<<a[j][1];
				} 
				cout<<endl; 
				for(int j=0;j<4;j++)
				{
					if(a[j][1]>=max[1])
					{
						max[1]=a[j][1];
						max[0]=j;
					}
				}
				a[max[0]][0]=b[i][1];
				a[max[0]][1]=0;
			}	
		}
		for(int i=0;i<4;i++)
		{
			a[i][1]++;
		}
	}
	return 0;
}
void suijishu()
{//产生随机数  
	cout<<"输入一个随机数: ";
	for(int i=0;i<320;i++)
	{
		c[i]=0;
	}
	int m,m1;
	int count;
	cin>>m;
	b[0][0]=m;
	b[1][0]=m+1;
	c[m]=1;
	c[m+1]=1;
	srand(time(0));
	for(int i=2;i<320;i=i+4)
	{
		int m1=rand()%m;
		count=0;
		while(c[m1]==1||c[m1+1]==1)
		{
			m1=rand()%m;
			count++;
			if((c[m1]==0||c[m1+1]==0)&&count>=50)
			{
				break;
			}
		}	
		b[i][0]=m1;
		b[i+1][0]=m1+1;
		c[m1]=1;
		c[m1+1]=1;
		int m=rand()%(318-m1)+m1+2;
		count=0;
		while(c[m]==1||c[m+1]==1)
		{
			m=rand()%(318-m1)+m1+2;
			count++;
			if((c[m]==0||c[m+1]==0)&&count>=50)
			{
				break;
			}
		}
		b[i+2][0]=m;
		b[i+3][0]=m+1;
		c[m]=1;
		c[m+1]=1;
	}
	int hh=0;
	for(int i=0;i<320;i++)
	{
		if(c[i]==1)
		hh++;
	}
	cout<<"所覆盖的指令条数: "<<hh<<"\n\n";
}
int main()
{
	suijishu();
	for(int i=0;i<320;i++)
	{
		b[i][1]=b[i][0]/10;
	}
	cout<<"********************************************* OPT"<<endl;
	opt();
	cout<<"********************************************* FIFO"<<endl;
	fifo();
	cout<<"********************************************* LRU"<<endl;
	lru();
	cout<<"\n\npage default rate..."<<endl;
	r1=cnt1/320*100;
	cout<<"OPT :"<<r1<<"%"<<endl;
	r2=cnt2/320*100;
	cout<<"FIFO:"<<r2<<"%"<<endl;
	r3=cnt3/320*100;
	cout<<"LRU :"<<r3<<"%"<<endl;
	return 0;
}

操作系统实验4 文件系统

//实验4-文件系统 
#define null 0
int files=0; //文件个数 ,初始文件个数为0 
int spares=0; //用于记录文件结构体数组中删除文件记录后留下的空位(若删除末尾文件则不记录) 
#include<string.h>
#include<iostream>
using namespace std;
struct file
{
	char name;
	int state; //state表示文件还是目录,目录为1,文件为2 
	int address;
	int length;
	int child;
	//int brother;
	int parent;
	string content;
};
struct file file[20]; //文件结构体数组 
int bitmap[20];	 //位示图
string disk_block[20]; //磁盘盘块数组 
char format()
{//格式化(将文件结构体数组、位示图、磁盘盘块全部清空) 
	char f;
	for(int i=0;i<20;i++)
	{
		//文件结构体数组初始化 
		file[i].name=null;
		file[i].state=null;
		file[i].address=null;
		file[i].length=0;
		file[i].child=null;
		file[i].parent=null;
		file[i].content="";	
		//位示图初始化 
		bitmap[i]=0;
		//磁盘盘块初始化 
		disk_block[i]=""; 
	}
	cout<<"输入根目录名:";
	cin>>f;
	file[0].name=f;
	file[0].state=1;
	file[0].address=null;
	file[0].length=0;
	file[0].child=null;
	file[0].parent=-1;	//根节点双亲结点赋为-1 
	files++;
	return f;	//返回根目录 
}
int mkdir(char cur,char f)
{//创建子目录 ,在当前目录cur下创建子目录f 
	cout<<"创建子目录..\n";
	//1.找到双亲结点所在位置 
	int p_pos;	//双亲结点所在位置
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].name==cur)
		{
			p_pos=i;
			break;
		}
	}
	//2.在文件结构体数组中找到空位并记录 
	if(spares!=0)
	{//文件结构体数组记录中间有空位 
		for(int i=0;i<files;i++)
		{
			if(!file[i].name)
			{//找到第一个空位 
				file[i].name=f;
				file[i].state=1;
				file[i].address=null;
				file[i].length=0;
				file[i].child=null;
				file[i].parent=p_pos;
				file[p_pos].child=i;
				files++;
				spares--;
				break;
			}
		}
	}
	else
	{//数组记录中无空位,在末尾文件记录的下一个位置记录 
		file[files].name=f;
		file[files].state=1;
		file[files].address=null;
		file[files].length=0;
		file[files].child=null;
		file[files].parent=p_pos;
		file[p_pos].child=files;
		files++;
	}
	return 0;
}
int rmdir(char cur,char f)
{//删除子目录 ,删除当前目录cur下的子目录f
	cout<<"删除子目录..\n";
	//1.判断当前目录cur下是否有子目录f
	int count=0;
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].name==f&&file[file[i].parent].name==cur)
		{ 
			count++;
			break;
		}
	}
	if(count==0)
	{
		cout<<"当前目录"<<cur<<"下没有目录"<<f<<endl; 
		return 0;
	}
	//2.删除该子目录f的所有子目录
	for(int i=0;i<files+spares;i++)
	{
		if(file[file[i].parent].name==f)
		{
			file[i].name=null;
			file[i].state=null;
			file[i].address=null;
			file[i].length=0;
			file[i].child=null;
			file[i].parent=null;
			//根据删除的文件记录的位置,确定文件结构体数组中空位spares的情况 
			if(i==files+spares-1)
			{
				if(!file[i-1].name)
				{
					int t=0,j=i-1;
					do
					{
						t++;
						j--;
					}while(!file[j].name);
					spares-=t;
					files--;
				}
				else
				{
					files--;
				}
			}
			else
			{
				spares++;
				files--;
			}
		}
	}
	//3.删除该子目录f的文件记录 
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].name==f&&file[file[i].parent].name==cur)
		{//找到当前目录cur下的子目录f,进行删除操作 
			file[i].name=null;
			file[i].state=null;
			file[i].address=null;
			file[i].length=0;
			file[i].child=null;
			file[i].parent=null;
			//根据删除的文件记录的位置,确定文件结构体数组中空位spares的情况 
			if(i==files+spares-1)
			{
				if(!file[i-1].name)
				{
					int t=0,j=i-1;
					do
					{
						t++;
						j--;
					}while(!file[j].name);
					spares-=t;
					files--;
				}
				else
				{
					files--;
				}
			}
			else
			{
				spares++;
				files--;
			}
		}
	}
	//4.若该子目录f是当前目录cur的唯一孩子结点,则将当前目录cur的孩子结点赋为空
	int n=0;
	for(int i=0;i<files+spares;i++)
	{
		if(file[file[i].parent].name==cur) 
		{
			n++;
		} 
	} 
	if(n==0)
	{
		for(int i=0;i<files+spares;i++)
		{
			if(file[i].name==cur)
			{
				file[i].child=null;
			}
		}
	}
	return 0;	
} 
int t0=0;
int recur(int m)
{//lsall()函数调用的递归函数,用来找文件结构体数组中位置为m的子目录的所有子目录 
	t0++;
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state&&file[i].parent==m)
		{
			for(int j=0;j<t0;j++)
			{
				cout<<"  ";
			}
			cout<<file[i].name<<endl;
			if(file[i].child)
			{
				recur(i);
			}
		}
	}
	t0--;
	return 0;
}
int lsall()
{//显示所有子目录 
	cout<<"显示所有目录:\n";
	cout<<file[0].name<<endl;
	recur(0);
	return 0;
}
int ls(char cur)
{//显示当前目录的子目录
	cout<<"显示目录:\n";
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state&&file[file[i].parent].name==cur)
		{
			cout<<"  ";
			cout<<file[i].name<<endl;
		}
	}
	return 0;
}
char cd(char f)
{//更改当前目录为f 
	int count=0;
	cout<<"更改当前目录..\n";
	for(int i=0;i<files+spares;i++)
	{//查看是否存在目录f 
		if(file[i].state==1&&file[i].name==f)
		{
			count++;
			break;
		}
	} 
	if(count==0)
	{
		cout<<"目录"<<f<<"不存在!\n"; 
	}
	return f;	//返回目录f 
}
int create(char cur,char f)
{//创建文件 
	cout<<"创建文件..\n";
	//1.找到双亲结点所在位置 
	int p_pos;	//双亲结点所在位置
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].name==cur)
		{
			p_pos=i;
			break;
		}
	} 
	//2.根据位示图分配一个盘块并在位示图上记录 
	int addr;
	for(int i=0;i<20;i++)
	{
		if(bitmap[i]==0)
		{
			bitmap[i]=1;
			addr=i;
			break;	
		}	
	} 
	//3.在文件结构体数组中找到位置并记录 
	if(spares!=0)
	{//文件结构体数组记录中间有空位 
		for(int i=0;i<files;i++)
		{
			if(!file[i].name)
			{//找到第一个空位 
				file[i].name=f;
				file[i].state=2;
				file[i].address=addr;
				file[i].length=1;
				file[i].child=null;
				file[i].parent=p_pos;
				file[i].content="";
				file[p_pos].child=i;
				files++;
				spares--;
				break;
			}
		}
	}
	else
	{//数组记录中无空位,在末尾文件记录的下一个位置记录 
		file[files].name=f;
		file[files].state=2;
		file[files].address=addr;
		file[files].length=1;
		file[files].child=null;
		file[files].parent=p_pos;
		file[files].content="";
		file[p_pos].child=files;
		files++;
	}
	return 0;
}
int open(char cur,char f)
{//打开文件 
	int count=0;
	cout<<"打开文件..\n";
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state==2&&file[i].name==f&&file[file[i].parent].name==cur)
		{//能够在当前目录cur下找到文件f
			count++;
			break; 
		}
	}
	if(count==0)
	{
		cout<<"当前目录下没有该文件!\n";
	}
	return count;
}
int write(char f)
{//写文件f 
	cout<<"写文件..\n";
	cout<<"输入文件内容:";
	string cont;
	cin>>cont;
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state==2&&file[i].name==f)
		{//找到文件f所在记录
			if(cont.length()<=5)
			{//长度小于等于5直接记入文件记录中 
				file[i].content=cont;
				break;
			}
			else
			{//长度大于5记入磁盘盘块中,并在文件记录中标记 
				file[i].content="#";
				disk_block[file[i].address]=cont;
				break;
			}
		}
	}
	return 0;
}
int read(char f)
{//读文件f 
	cout<<"读文件..\n";
	string cont;
	cout<<"文件内容:"; 
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state==2&&file[i].name==f)
		{//找到文件f所在记录
			if(file[i].content.length()&&file[i].content!="#")
			{//有内容且内容不是标记"#" 
				cout<<file[i].content<<endl;
			}
			else
			{
				if(file[i].content=="#")
				{//内容为标记"#" ,说明文件内容在对应磁盘盘块中 
					cout<<disk_block[file[i].address]<<endl;
				}
				else 
				{
					if(!file[i].content.length())
					{//文件内容为空,未写 
						cout<<"文件内容为空!\n";
					}
				}
			}
			break;
		}
	}
	return 0;
}
int rm(char cur,char f)
{//删除当前目录cur下的文件f 
	cout<<"删除文件..\n";
	//查看当前目录下cur是否有文件f,若有则记下所占物理空间的始址以待回收空间
	int addr; 
	int count=0;
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state==2&&file[i].name==f&&file[file[i].parent].name==cur)
		{
			addr=file[i].address;
			count++;
			break;
		}
	}
	if(count==0)
	{
		cout<<"当前目录下没有该文件!\n";
	}
	else
	{
		bitmap[addr]=0;	//修改位示图 
		disk_block[addr]="";	//磁盘所占盘块赋为空 
		//删除该文件记录 
		for(int i=0;i<files+spares;i++)
		{
			if(file[i].state==2&&file[i].name==f&&file[file[i].parent].name==cur)
			{//找到当前目录cur下的文件f ,进行删除操作 
				file[i].name=null;
				file[i].state=null;
				file[i].address=null;
				file[i].length=0;
				file[i].child=null;
				file[i].parent=null;
				file[i].content="";
				if(i==files+spares-1)
				{
					if(!file[i-1].name)
					{
						int t=0,j=i-1;
						do
						{
							t++;
							j--;
						}while(!file[j].name);
						spares-=t;
						files--;
					}
					else
					{
						files--;
					}
				}
				else
				{
					spares++;
					files--;
				}
				break;
			}
		}
		//若该文件f是当前cur目录的唯一孩子结点,则将当前目录cur的孩子结点赋为空
		int n=0;
		for(int i=0;i<files+spares;i++)
		{
			if(file[file[i].parent].name==cur) 
			{
				n++;
			} 
		} 
		if(n==0)
		{
			for(int i=0;i<files+spares;i++)
			{
				if(file[i].name==cur)
				{
					file[i].child=null;
				}
			}
		}
	}
	return 0;
}
int t1=0;
int coutpath(char cur)
{//输出当前目录cur及其路径(递归调用,倒序输出所经历的目录cur) 
	t1++;
	char curparent;	//目录cur的父目录 
	for(int i=0;i<files+spares;i++)
	{
		if(file[i].state==1&&file[i].name==cur)
		{//找到当前目录cur所在记录 
			if(file[i].parent==-1)
			{
				break;
			}
			curparent=file[file[i].parent].name;
			if(file[file[i].parent].parent!=-1)
			{
				coutpath(curparent);	//对目录cur的父目录继续调用coutpath()函数 
			}
			cout<<"/"<<curparent;
		}
	}
	t1--;
	if(t1==0)
	{
		cout<<"/"<<cur<<">";
	}
	return 0;
}
int main()
{
	char f,cur;
	string ins;
	cur=format();
	string fo_c="format",
		   mk_c="mkdir",
		   rm_c="rmdir",
		   lsall_c="lsall",
		   ls_c="ls",
		   cd_c="cd",
		   cr_c="create",
		   op_c="open",
		   cl_c="close",
		   wr_c="write",
		   re_c="read",
		   rmf_c="rm";
	while(1)
	{
		coutpath(cur);
		while(cin>>ins)
		{
			if(ins==fo_c)
			{
				cur=format();
				break;
			}
			if(ins==ls_c)
			{
				ls(cur);
				break;
			}
			if(ins==lsall_c)
			{
				lsall();
				break;
			}
			else
			{
				if(getchar()==10)
				{
					cout<<"输入有误.."<<endl;
					break;
				}
				if(cin>>f)
				{
					if(ins==mk_c)
					{
						mkdir(cur,f);
						break;	
					}
					if(ins==rm_c)
					{
						rmdir(cur,f);
						break;	
					}
					if(ins==cd_c)
					{
						cur=cd(f);
						break;
					}
					if(ins==cr_c)
					{
						create(cur,f);
						break;
					}
					if(ins==op_c)
					{
						if(open(cur,f)==0)
						{
							break;
						}
						coutpath(cur);
						if(cin>>ins>>f)
						{
							if(ins==wr_c)
							{
								write(f);
								coutpath(cur);
							}
							if(ins==re_c)
							{
								read(f);
								coutpath(cur);
							}
							if(ins==cl_c)
							{
								cout<<"关闭文件..\n";
								break;	
							}
						}
						if(getchar()==10)
						{
							char ch;
							ch=getchar();
							if((ins==re_c||ins==wr_c)&&ch==10)
							{
								cout<<"请先关闭文件!\n";
								coutpath(cur);
								if(cin>>ins>>f)
								{
									if(ins==cl_c)
									{
										cout<<"关闭文件..\n";
										break;	
									}
								}
							}
							if(cin>>ins>>f)
							{
								if(ch=='c'&&ins=="lose")
								{
									cout<<"关闭文件..\n";
									break;	
								}
							}
						}
					}
					if(ins==rmf_c)
					{
						rm(cur,f);
						break;
					}
					if(ins==wr_c||ins==re_c)
					{
						cout<<"读写文件前需打开文件!\n";
						break;
					}
					else
					{
						cout<<"输入有误.."<<endl;
						break;
					}
				}
			}
		};
		cout<<endl;
	};
	return 0;	
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值