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

📄 changerecord.cpp

📁 数据结构大作业的非界面版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//changerecord.cpp
///////////////////////////////////////////////////////////////////
#include"changerecord.h"
#include<iomanip.h>
#include<stdio.h>
#include<fstream.h>
#include<string.h>


//顺序打印出主文件fname1中的每个记录
////////////////////////////////////////////////////////////////////
void ChangeRecord::PrintMainFile(char* fname1)
{
	ifstream fin(fname1, ios::in|ios::nocreate|ios::binary);
	if(!fin)
	{
	  cerr<<fname1<<' '<<"not find!"<<endl;
	  return;
	}
	ElemType x;
	fin.seekg(0,ios::end);         //将文件指针移动到文件末
	int b1=sizeof(ElemType);
	int n=fin.tellg()/b1;          //用n表示文件所含的记录数	 
	int j=0;
	fin.seekg(0);                  //将文件指针移动到文件尾
	cout<<setw(20)<<"关键字"<<setw(20)<<"记录标识"
	    <<setw(14)<<"数据内容"<<endl;
	for(int i=0;i<n;i++) 
	{
	  fin.read((char*) &x, b1);     //从文件中读出一条记录
	  if(i%1==0)  
	    cout<<endl;                 //每行显示1条记录
	  if(x.key==DeleteMark)
	    continue;
	  if(x.kind==1)                 //链接方式输出链接文件的二进制内容
	  {
	    PrintLinkFile(x);
	  }
	  if(x.kind==0)                //字节流输出数据内容
	  {
	    cout<<setw(20)<<x.key<<setw(20)<<x.Mark
		<<setw(x.len+5)<<x.Elem;
	  }
	}
	cout<<endl;
	fin.close();
}

//顺序打印出索引文件fname2中每个有序索引项
///////////////////////////////////////////////////////////////////////////
void ChangeRecord::PrintIndexFile(char* fname2)
{
	ifstream fin(fname2, ios::in|ios::nocreate|ios::binary);
	if(!fin) 
	{
	  cerr<<fname2<<' '<<"not find!"<<endl;
	  return;
	}
	IndexItem x;
	fin.seekg(0,ios::end);         //将文件指针移动到文件末
	int b2=sizeof(IndexItem);
	int n=fin.tellg()/b2;          //用n表示文件所含的记录数
	fin.seekg(0);                  //将文件指针移动到文件尾
	cout<<setw(20)<<"关键字"<<setw(20)<<"记录存储位置"<<endl;  
	for(int i=0;i<n;i++) 
	{
	  fin.read((char*) &x, b2);    //从文件中读出一个索引项
	  if(i%1==0)  
	    cout<<endl;                //每行显示1个数据
	  cout<<setw(20)<<x.key<<setw(20)<<x.next;  
	}
	cout<<endl;
	fin.close();
}
//顺序打印出主文件fname1中的已删除的记录
////////////////////////////////////////////////////////////////////
void ChangeRecord::PrintDeleteFile(char* fname1)
{
	ifstream fin(fname1, ios::in|ios::nocreate|ios::binary);
	if(!fin)
	{
	  cerr<<fname1<<' '<<"not find!"<<endl;
	  return;
	}
	ElemType x;
	fin.seekg(0,ios::end);         //将文件指针移动到文件末
	int b1=sizeof(ElemType);
	int n=fin.tellg()/b1;          //用n表示文件所含的记录数	 
	int j=0;
	fin.seekg(0);                  //将文件指针移动到文件尾
	cout<<setw(20)<<"关键字"<<setw(20)<<"记录标识"
	    <<setw(14)<<"数据内容"<<endl;
	for(int i=0;i<n;i++) 
	{
	  fin.read((char*)&x, b1);     //从文件中读出一条记录
	  if(i%1==0)  
	    cout<<endl;                 //每行显示1条记录
	  if(x.key==DeleteMark)
	  {
	    if(x.kind==1)                 //链接方式输出链接文件的二进制内容
	    {
	      PrintLinkFile(x);
	    }
	    if(x.kind==0)                //字节流输出数据内容
	    {
	      cout<<setw(20)<<x.key<<setw(20)<<x.Mark
		  <<setw(x.len+5)<<x.Elem;
	    }
	  }
	  else continue;
	}
	cout<<endl;
	fin.close();
	
}


//向物理文件名为fname1指针所指字符串的主文件中追加n个记录
//////////////////////////////////////////////////////////////////////////
void ChangeRecord::MFAppend(char* fname1, char* fname2, ElemType a[], int n)
{
        //定义一个输出文件流对象ofs与主文件相联系
	ofstream ofs(fname1,ios::app|ios::binary);
	if(!ofs) 
	{
	  cerr<<fname1<<' '<<"not open!"<<endl;
	  return;
	}
        int i; 
	int b1=sizeof(ElemType);
        //把文件指针移动到文件尾
	ofs.seekp(0, ios::end);
        //求出当前文件长度
	int flen=ofs.tellp()/b1;
        //把a数组中的n个记录写入到文件中	
	for(i=0; i<n; i++) 
	  ofs.write((char*) &a[i], b1);
        //关闭文件ofs
	ofs.close();  
        //把a中n个记录的索引项依次插入到索引文件fname2中
	IndexItem x;
	for(i=0; i<n; i++) 
	{
	  x.key=a[i].key;
	  x.next=flen+i;
	  IFInsert(fname2, x); 
	}
}

//从物理文件名为fname1指针所指字符串的主文件中删除n个记录
//////////////////////////////////////////////////////////////////////////
void ChangeRecord::MFDelete(char* fname1, char* fname2, KeyType a[], int n)
{
        //定义一个输入输出文件流对象fio与主文件相联系
	fstream fio(fname1,ios::in|ios::out|
		ios::nocreate|ios::binary);
	if(!fio) 
	{
	  cerr<<fname1<<' '<<"not open!"<<endl;
	  return;
	}
        int b1=sizeof(ElemType);
	IndexItem x;
	ElemType y;
	int i;
        //依次删除每个记录	
	for(i=0; i<n; i++) 
	{
	  x.key=a[i];
	  bool k=IFDelete(fname2,x);
	  if(!k) 
	  {
	    cout<<"              ";
	    cout<<"关键字为"<<x.key<<"的记录不存在"<<endl;
	    continue;
	  }
	  fio.seekg(x.next*b1);
	  fio.read((char*) &y, b1);
	  y.key=DeleteMark;
	  fio.seekg(-b1, ios::cur);
	  fio.write((char*) &y, b1);
	  cout<<"              ";
	  cout<<"关键字为"<<x.key<<"的记录被删除"<<endl;
	}
	fio.close();  
}

//从物理文件名为fname1指针所指字符串的主文件中查找n个记录
////////////////////////////////////////////////////////////////////////////
void ChangeRecord::MFSearch(char* fname1, char* fname2, KeyType a[], int n)
{
	//定义一个输入输出文件流对象ifs与主文件相联系
	ifstream ifs(fname1,ios::in|ios::nocreate|ios::binary);
	if(!ifs) 
	{
	  cerr<<fname1<<' '<<"not open!"<<endl;
	  return;
	}
        int b1=sizeof(ElemType);
	IndexItem x;
	ElemType y;
	int i;
        //依次查找每个记录
	for(i=0; i<n; i++) 
	{
	  x.key=a[i];
	  bool k=IFSearch(fname2,x);
	  if(!k) 
	  {
	    cout<<"              ";
	    cout<<"查找关键字为"<<x.key<<"的记录失败!"<<endl;
	    continue;
	  }
	  ifs.seekg(x.next*b1);
	  ifs.read((char*) &y, b1);
	  cout<<"              ";
	  cout<<"查找关键字为"<<x.key<<"的记录成功!"<<endl;
	  cout<<"=========================================================="<<endl;
	  cout<<"              该记录内容为"<<endl;
	  cout<<"=========================================================="<<endl;
	  if(y.kind==1)                 //链接方式输出链接文件的二进制内容
	    {
	      PrintLinkFile(y);
	    }
            if(y.kind==0)                //字节流输出数据内容
	    {
	      cout<<setw(20)<<y.key<<setw(20)<<y.Mark
		  <<setw(y.len+5)<<y.Elem;
	    }
	    cout<<endl;
	}
	ifs.close();  
}

//把一个记录的索引项插入到有序数组A中
///////////////////////////////////////////////////////////////////////////
void ChangeRecord::SeqInsert(IndexItem A[], int mm, IndexItem x)
{
        for(int i=mm-1; i>=0; i--) 
	{  
	  //从尾部向前为寻找插入位置进行顺序比较和移动
          if(A[i].key>x.key)
	    A[i+1]=A[i];
          else 
	  {
	    A[i+1]=x;
	    break;
	  }
	}
        if(i<0) 
	  A[0]=x;
}

//向由fname2指针所表示的索引有序文件中插入x索引项
/////////////////////////////////////////////////////////////////////////////
void ChangeRecord::IFInsert(char *fname2, IndexItem x)
{
        //以输入方式打开由fname2指针所表示的索引有序文件
        ifstream ifs(fname2, ios::in|ios::binary);
        if(!ifs) 
	{
          cerr<<fname2<<' '<<"not open!"<<endl;
	  return;
	}
        //以输出方式打开temp文件
	ofstream ofs("temp",ios::out|ios::binary);
	if(!ofs) 
	{
	  cerr<<"temp"<<' '<<"not open!"<<endl;
	  return;
	}
        //动态定义一个具有m+1个元素的数组A
        IndexItem* A=new IndexItem[m+1];
        //将原文件指针指向文件开始位置,此语句可以省略
	ifs.seekg(0);
        //通过while循环完成插入操作
	int b2=sizeof(IndexItem);
	while(1)
	{
          ifs.read((char*)A, m*b2);
	  int s=ifs.gcount()/b2;
	  //读入数组A的世纪索引项数被存入s中
	  if(s==m)
	  {  
	    if(A[m-1].key<x.key) 
	    {
	      ofs.write((char*)A, m*b2);
	    }
            else 
	    {
	      SeqInsert(A, m, x);  //将x索引项插入到有序数组A中
	      ofs.write((char*)A,(m+1)*b2);
	      while(!ifs.eof()) 
	      {  
		//把原文件中剩余的所有记录写入到结果文件中
	        ifs.read((char*)A, m*b2);
		s=ifs.gcount()/b2;
		ofs.write((char*)A, s*b2);
	      }
	      break;  //退出while(1)循环
	    }
	  }
	  else
	  {
	    SeqInsert(A, s, x);
	    ofs.write((char*)A, (s+1)*b2);
	      break; //处理完最后一个数据块后退出while(1)循环
	  }
	}
	delete [] A;
	ifs.close();
	ofs.close();
	remove(fname2);
	rename("temp", fname2);
}


//从有序数组A中删除一个关键字为x.key的索引项
/////////////////////////////////////////////////////////////////////////////
bool ChangeRecord::SeqDelete(IndexItem A[], int mm, IndexItem& x)
{
        //从数组A的首元素开始顺序查找关键字为x.key的索引项
	int i=0;
	while(i<mm && A[i].key<x.key)
	  i++;
        //若不存在待删除的索引项则返回假
	if(i==mm || A[i].key!=x.key) return false;
        //被删除的索引项赋给x带回
	x=A[i]; 
        //使i1至m-1的所有元素前移一个位置
	for(int j=i+1; j<mm; j++) 
	  A[j-1]=A[j];
        //返回真表示删除成功
	return true;
}

//从由name2指针所表示的索引有序文件中删除关键字为x.key的索引项,并由x带回被删除的索引项
///////////////////////////////////////////////////////////////////////////////////////////
bool ChangeRecord::IFDelete(char*fname2,IndexItem&x)
{
        //以输入方式打开由fname2指针所表示的索引有序文件
	ifstream ifs(fname2, ios::in|ios::nocreate|ios::binary);
	if(!ifs) 
	{
	  cerr<<fname2<<' '<<"not found!"<<endl;
	  return false;
	}
        //以输出方式打开temp文件
	ofstream ofs("temp",ios::out|ios::binary);
	if(!ofs) 
	{
	  cerr<<"temp"<<' '<<"not open!"<<endl;
	  return false;
	}
        int b2=sizeof(IndexItem);
        //动态定义一个具有m个元素的数组A
	IndexItem* A=new IndexItem[m];
        //用d等于true或false表示删除是否成功
	bool d;  
        //通过while完成删除操作
	while(1)
	{
          ifs.read((char*)A, m*b2);
	  int s=ifs.gcount()/b2;
	  //读入数组A的实际索引项数被存入s中
	  if(s==m)
	  { 
	    if(A[m-1].key<x.key) 
	    {
	      ofs.write((char*)A, m*b2);
	    }
            else 
	    {
	      d=SeqDelete(A, m, x);
	      if(d) 
		ofs.write((char*)A,(m-1)*b2);
	      else 
		ofs.write((char*)A,m*b2);
	      while(!ifs.eof()) 
	      { 
	        //把原文件中剩余的所有记录写入到结果文件中
		ifs.read((char*)A, m*b2);

⌨️ 快捷键说明

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