📄 filefunction.h
字号:
#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 + -