⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dzy.cpp

📁 一个数据结构的大作业
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include<fstream>
#include<string>
#include<iostream>
#include<cstdlib>
using namespace std;

/**************************************************************/

const int LINKLENGTH=50;             //链接的最大长度
const int DATANODELENGTH=100;        //字节流节点最大长度
const int KEYLENGTH=50;              //记录标识最大长度

/**************************************************************/

/**************************************************************/
const int FILENAME=100;            //文件名的最大长度
const int PATHLENGTH=100;         //路径最大长度
/**************************************************************/

/**************************************************************/
/************************类声明开始****************************/
/**************************************************************/

typedef struct         //该结构用于定义一个记录头类型
{
	int num;                //记录号
	char key[KEYLENGTH];    //记录标识
	bool deletionSign;      //删除标志,1已删,0未删
    long length;            //数据块长度
	int tag;                //记录标签(LINk==0:链接;SUBFILE==1:多媒体文件)
}RecordNode;

typedef struct DataNode  //该结构用于定义数据结点
{
	   char str[DATANODELENGTH];  //字节流节点
	   DataNode * next;           //下一个数据结点
}DataNode;

struct NumNode       //该结构用于定义一个记录文件所含记录数的索引
{
	int num;				//记录文件中所含有的记录数
	char name[FILENAME];    //记录文件的名称
};

/**************************************************************/

class RecordFile
{
	RecordNode recordHead;           //记录头
    DataNode * data;                 //数据部分头指针
public:
	RecordFile();                    //构造函数
    ~ RecordFile();                  //析构函数
	void SetNum(int n);              //设置记录号
	int GetNum();                    //得到记录号
	void SetKey(char * k);           //设置记录标识
	char * GetKey();                 //得到记录标识
	void SetDeletionSign(bool d=0);  //设置删除标志
	bool GetDeletionSign();          //得到删除标志
	void SetLength(long l);          //设置数据块长度
	long GetLength();                //得到数据块长度
	void SetTag(int t);              //设置标签
	int GetTag();                    //得到标签
    void SetData(DataNode * s);      //设置数据
	DataNode * GetData();            //得到数据
	void SequenceReadHead(fstream & f);  //对记录头进行顺序读
	void SequenceReadData(fstream & f);  //对数据部分进行顺序读
	void SequenceWriteHead(fstream & f); //对记录头进行顺序写
	void SequenceWriteData(fstream & f); //对数据部分进行顺序写
	void ReleaseSpace();                 //释放各数据结点空间
};

/**************************************************************/
/************************类声明结束****************************/
/**************************************************************/

/**************************************************************/
/************************函数声明开始**************************/
/**************************************************************/

void CreateFile();                //创建文件

void OpenFile();                  //打开文件

void OperateFile(fstream & f,char * fileName);//对打开的文件进行相关操作

void ViewFile();                  //查看已存在的文件

void AddRecord(fstream & f,char * fileName);  //加入记录

void DeleteRecord(fstream & f);   //删除记录

void LocateRecord(fstream & f);   //定位记录

void ModifyRecordTag(fstream & f);//修改记录标识

void RewriteRecord(fstream & f,char * fileName);  //重写一条记录

void ProduceNewFile(fstream & f); //写为新文件

void CountNum(fstream & f);       //计数并列出记录列表

void Browse(fstream & f);         //浏览记录文件内容

//输入子文件详细资料
void InputDetails(fstream & f,RecordFile & RF,char * fileName);

/**************************************************************/
/************************函数声明开始**************************/
/**************************************************************/


/**************************************************************/
/**********************主函数开始******************************/
/**************************************************************/
int main()
{
	
	char choice,ch;
	/*************创建索引文件******************/
	fstream index("index.dat",ios::binary);
	index.close();

	while(1)
	{
	 
	 cout<<"| * * * * * * * * * * * *变长记录文件* * * * * * * * * * * * |"<<endl;
	 cout<<"| 请键入操作选择:                                            |"<<endl;
	 cout<<"| 1:创建一个新文件                                           |"<<endl;
	 cout<<"| 2:打开一个已存在文件                                       |"<<endl;
	 cout<<"| 3:查看已存在的变长记录文件                                 |"<<endl;
	 cout<<"| 0:关闭该系统                                               |"<<endl;
	 cout<<"| * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  |"<<endl;
	 cin>>choice;
	 switch(choice)
	 {
	 case '1':CreateFile();     break;
	 case '2':OpenFile();	    break;
	 case '3':ViewFile();	    break;
	 case '0':
		 cout<<"你真的想退出系统(Y/N)?\n";
		 cin>>ch;
		 if(ch=='y'||ch=='Y')	return 0;
		 else break;
	 default:cout<<"输入错误,请重新输入\n\n";
	 }

	}
	return 0;
}

/**************************************************************/
/**********************主函数结束******************************/
/**************************************************************/


/**************************************************************/
/******************类函数定义开始******************************/
/**************************************************************/

RecordFile::RecordFile()                    //构造函数,令头指针为空
{
	data=NULL;
}

/**************************************************************/

RecordFile::~RecordFile()                   //析构函数,将各数据结点空间释放
{	
	DataNode * p;
	while(data)
	{
		p=data;
		data=data->next;
		delete p;
	}
	recordHead.length=0;
}

/**************************************************************/

void RecordFile::SetNum(int n)              //设置记录号
{	recordHead.num=n;	}

/**************************************************************/

int RecordFile::GetNum()                    //得到记录号
{	return recordHead.num;	}

/**************************************************************/

void RecordFile::SetKey(char * k)           //设置记录标识
{	strcpy(recordHead.key,k);	}

/**************************************************************/

char * RecordFile::GetKey()                 //得到记录标识
{	return recordHead.key;	}

/**************************************************************/

void RecordFile::SetDeletionSign(bool d)   //设置删除标志
{	recordHead.deletionSign=d;	}

/**************************************************************/

bool RecordFile::GetDeletionSign()         //得到删除标志
{	return recordHead.deletionSign;	}

/**************************************************************/

void RecordFile::SetLength(long l)         //设置数据块长度
{	recordHead.length=l;	}

/**************************************************************/

long RecordFile::GetLength()               //得到数据块长度
{	return recordHead.length;	}

/**************************************************************/

void RecordFile::SetTag(int t)             //设置标签
{	recordHead.tag=t;	}

/**************************************************************/

int RecordFile::GetTag()                   //得到标签
{	return recordHead.tag;	 }

/**************************************************************/

void RecordFile::SetData(DataNode * d)     //设置数据
{
	data=d;
}

/**************************************************************/

DataNode * RecordFile::GetData()          //得到数据
{	return data;	}

/**************************************************************/

void RecordFile::SequenceReadHead(fstream & f)          //对记录头进行顺序读
{
	f.read((char*)&recordHead,sizeof(RecordNode));
}

/**************************************************************/

void RecordFile::SequenceReadData(fstream & f)          //对数据部分进行顺序读
{
	long sum=0;
	DataNode * s,* p;
	s=new DataNode;
	while(sum<recordHead.length)
	{
		f.read(s->str,DATANODELENGTH-1);
		s->str[DATANODELENGTH-1]='\0';
		if(data==NULL)	data=s;
		p=s;
		s=new DataNode;
		p->next=s;
		sum+=DATANODELENGTH-1;
	}
	p->next=NULL;
	delete s;
}


/**************************************************************/

void RecordFile::SequenceWriteHead(fstream & f)     //对记录头进行顺序写
{
	f.write((char*)&recordHead,sizeof(RecordNode));
}

/**************************************************************/

void RecordFile::SequenceWriteData(fstream & f)     //对数据部分进行顺序写
{
	long sum=0;
	DataNode * s;
	s=data;
	while(s)
	{
		f.write(s->str,DATANODELENGTH-1);
		s=s->next;
	}
}

/**************************************************************/

void RecordFile::ReleaseSpace()                      //释放各数据结点空间
{	
	DataNode * p;
	while(data)
	{
		p=data;
		data=data->next;
		delete p;
	}
}
/**************************************************************/
/******************类函数定义结束******************************/
/**************************************************************/


/**************************************************************/
/****************其它函数定义开始******************************/
/**************************************************************/


void CreateFile()              //创建文件
{
	char ch,fileName[FILENAME],s[FILENAME];
	NumNode NN;
	cout<<"请为新文件命名:(请加后缀.dat)[如想返回可按0]"<<endl;
	cin>>fileName;
	if(strcmp(fileName,"0")==0) return;
	/*打开文件existFile.dat用于存放已经存在的变长记录文件*/
	fstream existFile("existFile.dat",ios::binary|ios::in|ios::out);
	if(!existFile)
    {
		cerr<<"existFile.dat文件不能打开!"<<endl;
		return;
	}
	long track=existFile.tellg();
	existFile.seekg(0,ios::end);
	long posEnd=existFile.tellg();
	existFile.seekg(0);
	while(track!=posEnd&&strcmp(fileName,s))
	{
		existFile.read(s,FILENAME-1);
		track=existFile.tellg();
	}
	if(strcmp(s,fileName)==0)
	{
		cout<<fileName<<"文件已经存在,要将该文件重写吗?(Y/N)"<<endl;
		cin>>ch;
		if(ch=='y'||ch=='Y'){
			cout<<"文件将被重写"<<endl;
			fstream index("index.dat",ios::out|ios::in|ios::binary);
			track=index.tellg();
			index.seekg(0,ios::end);
			posEnd=index.tellg();
			index.seekg(0);
			while(strcmp(fileName,NN.name)!=0)
			{
				index.read((char*)&NN,sizeof(NN));
				track=index.tellg();
			}
			NN.num=0;
			index.seekg(-sizeof(NN),ios::cur);
			index.write((char*)&NN,sizeof(NN));
		}
		else 
		{
			cout<<"返回至上一步"<<endl;
			existFile.close();
			return;
		}
	}
	else
	{
		existFile.seekp(0,ios::end);
		existFile.write(fileName,FILENAME-1); //将创建的文件放入existFile.dat中
	}
	existFile.close();                      //关闭文件existFile.dat
	fstream f;
	f.open(fileName,ios::binary|ios::in|ios::out|ios::trunc);
	if(!f)
	{
		cerr<<"fileName"<<"文件不能打开!"<<endl;
		return;
	}
	OperateFile(f,fileName);
	f.close();
}

/**************************************************************/

void OpenFile()          //打开文件
{
	char fileName[FILENAME];
	cout<<"请输入所要打开的文件名:(请加后缀.dat)[如想返回可按0]"<<endl;
	cin>>fileName;
	if(strcmp(fileName,"0")==0)return;
	fstream f(fileName,ios::binary|ios::in|ios::out);
	if(!f)
	{
		cerr<<fileName<<"文件不能打开,可能还未创建!"<<endl;
		return;
	}
	OperateFile(f,fileName);
	f.close();
}

/**************************************************************/

void ViewFile()         //查看已存在的文件
{
	char fileName[FILENAME];
	fstream existFile("existFile.dat",ios::binary|ios::in);
	if(!existFile)
    {
		cerr<<"existFiled.dat文件不能打开!"<<endl;
		return;
	}

	existFile.seekg(0,ios::end);             //读指针移到文件末尾
	long cur,posEnd=existFile.tellg();           //记录文件尾位置
	if(posEnd==0)cout<<"没有建立任何变长记录文件!"<<endl;
	else{
		cout<<"已存在的文件有:"<<endl;
		existFile.seekg(0,ios::beg);
		do{                              //输出已存在的文件名
			existFile.read(fileName,FILENAME-1);
			cout<<fileName<<endl;
			cur=existFile.tellg();
		}while(cur!=posEnd);
	}
	existFile.close();
}

/**************************************************************/

void OperateFile(fstream & f,char * fileName)   //对打开的文件进行相关操作
{
	while(1)
	{
	char choice;
	cout<<"| * * * * * * * * * * 对变长记录文件操作 * * * * * * * * * * |"<<endl;
	cout<<"| 请键入操作选择:                                            |"<<endl;
	cout<<"| 1.加入记录                                                 |"<<endl;
	cout<<"| 2.删除记录                                                 |"<<endl;
	cout<<"| 3.定位记录                                                 |"<<endl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -