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

📄 filefunction.h

📁 数据结构大作业——变长记录文件存取类库 设计一个类库
💻 H
📖 第 1 页 / 共 4 页
字号:

#ifndef FILEFUNCTION_H
#define FILEFUNCTION_H

#include <iostream>
#include<fstream>
#include<iomanip>
#include<stdlib.h>
#include <fcntl.h>
#include <io.h>
#include<stdio.h>
#include<string>
#include<list>                               //STL顺序容器中的双向链表
#include<iterator>                           //STL中的组件:迭代器
#include <algorithm> 

using namespace std;							//使用名空间

struct record                                   //记录
{
	record(): data_num(0), deletetag(false),blocklength(0)
	{
		fname= new char[255];
        recordtag = new char[500];
		strcpy( recordtag, "no record");
	}
	string data;							 //数据部分                      
	int data_num;							 //记录号
	char *recordtag;						 //记录标识
	bool deletetag;                          //删除标识
	int blocklength;						 //数据块长度
	char *fname;						     //文件名
};


class function                              //基本功能
{
public:	
   	function();							//功能类的构造函数,对各变量初始化
	void fileprocess( );				//处理文件
	void filelink(int );				//链接文件
	void filebrowse(int );		    	//浏览文件
	void locate(int );					//按记录号定位函数
	void recordlocate(char *);			//按记录标识定位函数
	void filelocate( char *);			//按文件名定位函数
	void recordmodify(int );			//修改记录标识函数
	void filedelete();					//删除文件
	void fileopen();     
	//打开函数,从外存将全部内容写入缓存区。
	void fileclose();
	//关闭文件函数,关闭一个已打开的文件,并将缓冲区全部内容写回外存
    void sequentialread();          //顺序读函数
	void sequentialwrite();         //顺序写函数
	
	void Modify();					//修改记录
	void Append();					//加入记录
	void Rewrite();                 //重写记录
	
	int getread() const;			//获得读指针在链表中的位置
	int getwrite() const;			//获得写指针在链表中的位置
	void index();					//建立索引函数

private:
   list <record>  Listlink;								//建立记录双向链表
   record temp;
   int dnum;											 //记录最后一个记录号
   list<record>::iterator  currentread;                  //当前读指针
   list<record>::iterator  currentwrite;         		 //当前写指针
   list<record>::iterator  currenttemp;
};


function::function():dnum(0)            //构造函数
{
	    currentread = Listlink.begin();
		currentwrite = Listlink.begin();  
		currenttemp = Listlink.begin();
		fileopen();						//构造函数调用,将外存信息读入内存
}


void function::fileprocess( )			
//文件处理函数          
{
Line1:
	char *filename = new char[50];
	int c=1;
	cout << "\n请输入你要打开的文件路径:" << endl;
	cin >> filename;
			
	if(!filename)              //若输入不成功,放弃
	{
		cerr << "文件无法打开" << endl;
		abort();
	}
	
	else
	{
		fstream file( filename,ios::binary | ios::in);    //读文件
		if( !file.fail() )                    //若文件存在
		{
			list<record>::iterator outemp;    
			int x=0;
			for( outemp=Listlink.begin(); outemp!=Listlink.end(); outemp++)
			//文件已存在,进一步判断文件是否存在于记录中
			{
			   char aa[500];
				strcpy( aa, (*outemp).fname );
				if( strcmp((*outemp).fname, filename)==0 )      
				{
					x++;
				}
				if( x==1 ){ break; }   
			}
			file.close();
		
			if(x==1)							//文件存在于记录中
			{
			    int y;
				cout << "\n记录中存在与您输入的文件名相同的文件,请输入你的选择:\n";
				cout << "1--------覆盖该记录\n";
				cout << "2--------在该记录追加写入(非文本文件不推荐)\n";
				cout << "3-------重新输入文件名\n";
				//文件存在于记录中的操作
				cin >> y;

				switch(y)
				{
				 case 1:
					{
						file.close();
						ofstream outfile;
				    	outfile.open(filename, ios::out | ios::binary);    //Creating a file. If the file already exists, the old version is deleted.
	
						cin.clear();
						cout << "请输入内容: \n";
						cin.get();
						outfile << cin.rdbuf();

						delete [](*outemp).recordtag;
						(*outemp).recordtag = new char[500];
						strcpy( (*outemp).recordtag, "no record");
						cout << "\n请输入记录标志:\n";
						cin >> (*outemp).recordtag;     //输入记录标识
							
						outfile.seekp(0,ios::end);      //文件尾
						long pos=outfile.tellp(); 
						outfile.seekp(0,ios::beg);      //文件头
						pos-= outfile.tellp();			//求文件长度
						(*outemp).blocklength = pos;    
						outfile.close();
						break;
					}
				
				 case 2:
					{
						file.open(filename, ios::app | ios::binary | ios ::out);

						cout << "\n请输入记录标志:\n";
						cin >> (*outemp).recordtag;
						
						cout << "请输入内容: \n";
						cin.get();
						file << cin.rdbuf();

						file.seekp(0,ios::end);
						long pos=file.tellp();
						file.seekp(0,ios::beg);
						pos-= file.tellp();
						(*outemp).blocklength = pos;
						file.close();
						break;
					}

				case 3:
					{
						goto Line1;
						break;
					}
				default: 
					{
						cout << "输入有误\n";
						break;
					}
				}
			}

			if(x==0)                          //记录中不存在该文件
			{
				int y;
				cout << "\n记录中不存在与您输入的文件名相同的文件,但你输入的路径有同名文件存在,请输入你的选择:\n";
				cout << "1--------覆盖该文件\n";
				cout << "2--------在该文件追加写入\n";
				cout << "3--------建立与该文件的链接\n";
				cout << "4-------重新输入文件名\n";
				//文件存在中但不存在于记录中的操作
				cin >> y;

				switch(y)
				{
				 case 1:
					{
						strcpy( temp.fname, filename);
					    sequentialwrite();
						break;
					}
				 case 2:
					{
						dnum++;
						temp.data_num = dnum;
						strcpy( temp.fname, filename);
						file.open(filename, ios::app | ios::binary | ios::out);
						//追加方式加入内容
						cout << "\n请输入追加的内容: \n";
						cin.get();
						file << cin.rdbuf();

						cout << "请输入记录标志:\n";
						cin >> temp.recordtag;

						file.seekp(0,ios::end);
						long pos=file.tellp();
						file.seekp(0,ios::beg);
						pos-= file.tellp();
						temp.blocklength = pos;
						file.close();

						Listlink.push_back(temp);			//调用标准容器接口,加到链表尾部
						if(dnum==1)
						{ 
							currentwrite=Listlink.begin(); 
							cout << "建立第" << (*currentwrite).data_num << "个记录" << endl;
							currentread=Listlink.begin();
						}
						else 
						{
							currentwrite++;
							cout << "建立第" << (*currentwrite).data_num << "个记录" << endl;
						}
						
						temp.data_num = 0;
						temp.fname = new char[255];
						temp.recordtag = new char[500];
						strcpy( temp.recordtag, "no record");
						temp.deletetag = false;
						temp.blocklength = 0;
						break;
					}
				 case 3:
					 {
						 strcpy( temp.fname , filename);
						 dnum++;
						 temp.data_num = dnum;
						
						 cout << "\n请输入记录标志:\n";
						 cin >> temp.recordtag;
						 
						 file.open(filename, ios::binary | ios::in);
						 file.seekp(0,ios::end);
						 long pos=file.tellp();
						 file.seekp(0,ios::beg);
 						 pos-= file.tellp();
 						 temp.blocklength = pos;
 						 file.close();

						 Listlink.push_back(temp);
						 if(dnum==1)
						{ 
							currentread++;
						}
							currentwrite++;
							cout << "建立第" << (*currentwrite).data_num << "个记录" << endl;
						
						
						temp.data_num = 0;
						
						temp.fname = new char[255];
						temp.recordtag = new char[500];
						strcpy( temp.recordtag, "no record");
						temp.deletetag = false;
						temp.blocklength = 0;
						break;
					 }
				 case 4:
					 {
						goto Line1;
						break;
					 }
				default: 
					{
						cout << "输入有误\n";
						break;
					}
				}
			}
		}
		
		else										//文件不存在
		{
			strcpy(temp.fname, filename);
			sequentialwrite();
		}
    }
}



void function::filebrowse(int b )
// 浏览文件
{
	locate(b);
	if( (*currenttemp).deletetag==false )       //文件未被删除
	{
		ifstream inf;
		inf.open( (*currenttemp).fname , ios::in | ios::binary);
    
	    (*currenttemp).data="";
		char *arr = new char[6];
		do										//输出所有记录
		{
			memset(arr,0,6);                   //将arr[0]~arr[5]清0
			inf.read(arr,5);                   //读入arr
			(*currenttemp).data+=arr;		   //data是一个string字符流
		}
		while(!inf.eof());	                   //遇到文件结束符中止,否则循环
	
		cout << "\n记录内容是:\n";
		cout << setw(100) << setiosflags(ios::left) << (*currenttemp).data << endl;  
		//输出记录数据
		cout << "记录标志是:\n";
		cout << setw(100) << setiosflags(ios::left) << (*currenttemp).recordtag << endl;
		//输出记录标志
		inf.close();
	}
	else
	{
		cout << "文件已被删除!\n";
	}
}
	



void function::locate(int x)
//按记录号定位函数
{
	if( x<= dnum )
	{
		currenttemp=Listlink.begin();
		for( int i=1; i<x; i++)
		{
			currenttemp++;
		}
	}
	
	else
	{
		cout << "\n输入错误\n";
		temp.data_num=-1;
		return;
	}

	
	if( currenttemp==Listlink.end() )
	{
		cout << "\n不存在该记录\n";
		return;
	}
}


void function::recordlocate(char *arr)
//按记录标识定位函数
{
	while( currenttemp!=Listlink.end() )
	{
		string Data1="";
		Data1+=(*currenttemp).recordtag;
		if( (Data1.find(arr))!=-1)         //调用string类的查找函数
		{
			 cout << "与你输入条件匹配的有第" << (*currenttemp).data_num << "个记录" << endl;
			 break;
		}
		else
		{
			currenttemp++;
		}
	}
	
	if( currenttemp==Listlink.end() )
	{
		cout << "\n不存在该记录\n";
	}

	if( currenttemp==Listlink.end() )
	{
		cout << "\n不存在该记录\n";
	}
}


void function::filelocate(char *s)
//按记录标识定位函数
{
	currenttemp=Listlink.begin();
	while( currenttemp!=Listlink.end() )
	{
		if( strcmp( (*currenttemp).fname, s )==0 )         //若记录文件名与输入文件名相同
		{
			cout << "与你输入条件匹配的有第" << (*currenttemp).data_num << "个记录" << endl;
			break;
		}
		currenttemp++;

		if( currenttemp==Listlink.end() )
		{
			cout << "该文件不存在于记录中\n";
		}
	}

	if( Listlink.begin()==Listlink.end() )
	{
		cout << "不存在记录\n ";
	}
}



void function::recordmodify(int x)
//修改记录标识函数
{
	locate(x);
	if( temp.data_num!=-1)
	{
		cout << "原记录标识是:" << (*currenttemp).recordtag << endl;
		delete [](*currenttemp).recordtag;
		(*currenttemp).recordtag = new char[500];
		strcpy( (*currenttemp).recordtag, "no record");
		cout << "\n请输入新的记录标志\n";
		cin >> (*currenttemp).recordtag;
		cout << "修改成功\n";
	}
	else
	{
		cout << "输入错误\n";
	}
}


void function::filedelete()
//删除文件
//按记录号或标识删除记录;
//删除当前记录;
{
  int z;
  do
  {
	cout << "\n请键入你的选择:\n ";
	cout << "1-------按记录号删除记录\n";
	cout << "2-------删除当前读指针记录\n";
	cout << "3-------删除当前写指针记录\n";
	cout << "4-------按标识删除记录\n";
	cout << "0-------返回主目录\n ";
	cin >> z;
	switch(z)
	{
	case 0:break;
	case 1:						//按指定记录号删除
		{	
			int b;
			cout << "请输入要删除的记录号:\n";
			cin >> b;
			if( b<=dnum )
			{
				char ch='n';
				cout << "确认删除? (Y/N) \n" ;
				cin >> ch;
				if( ch =='Y' || ch =='y' || ch =='N' || ch =='n')
				{
				  if( ch =='Y' || ch =='y')
				  {
					cout << "删除第" << b << "个记录的文件 \n";
					
					locate(b);
				    if( (*currenttemp).deletetag==false)
					{
						ofstream deletingFile;
						_unlink((*currenttemp).fname); // 删除这个文件
						(*currenttemp).deletetag = true;
						(*currenttemp).blocklength = 0;
						delete [](*currenttemp).fname;
						delete [](*currenttemp).recordtag;
						(*currenttemp).fname = new char[255];
						strcpy( (*currenttemp).fname, "C:\\RECYCLED" );
						//删除后对文件名重新赋值,把路径默认为c盘的回收站
						(*currenttemp).recordtag = new char[500];
						strcpy( (*currenttemp).recordtag, "no record");
						//删除后对记录标识赋值为"no record"
						cout << "删除成功!" << endl;
						break;
					}
					else
					{
						cout << "该记录之前已被删除\n";
						break;
					}
				  }	
			

⌨️ 快捷键说明

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