二进制结构删除错误

Binary structure delete error

本文关键字:错误 删除 结构 二进制      更新时间:2023-10-16

这是整个程序。现在,delete函数不写入临时文件。我将尝试将str数组更改为string,看看是否有帮助。

程序应该能够读、写、编辑、搜索和排序有结构的二进制文件。

#include <cstdlib>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include<string>
#include<limits>
#include<iomanip>
#include<stdio.h>
#include <errno.h>
using namespace std;
const int SIZE=40;
char typedef str[SIZE];
char fname[]="c:/solident.dat";
char tname[]="c:/temp.dat";
struct Rec{int id;str lname,fname;};

//prototypes
void menu(string&);
void engine(string&,Rec&,fstream&,fstream&,int,char[],char[]);
void openFile(char[]);
void addRec(Rec&,char[]);
void delAll(char[]);
void listAll(Rec&,fstream &,char[]);
void appRec(Rec&,fstream &,char[]);
void delRec(Rec&,fstream &, fstream &,char[],char []);
void srcRec(Rec&,fstream& ,char[]);
void modRec(Rec &J,fstream &outfile, char fname[]);
void sort();
int main(int argc, char *argv[])
{
string choice;
Rec Student;
fstream infile;
fstream outfile;
do
    {    
        menu(choice);
        engine(choice,Student,infile,outfile,SIZE,fname,tname);
    } while(choice[0]!='0');  

    system("PAUSE");
    return EXIT_SUCCESS;
}
//function menu
void menu(string &choice)
{
    cout<<"nnntt========================"; 
    cout<<"nnttMENU n";
    cout<<"ntt========================nn";
    cout<<"tt[1] Open/check filen";
    cout<<"tt[2] Add recordsn";
    cout<<"tt[3] Append recordsn";
    cout<<"tt[4] Search for a recordn";
    cout<<"tt[5] Delete a recordn";
    cout<<"tt[6] Delete all recordsn";
    cout<<"tt[7] Modify a recordn";
    cout<<"tt[8] List all recordsn";
    cout<<"tt[9] Sort all recordsn";
    cout<<"tt[0] Exitn";
    cout<<"ntt========================= n";
    cout<<"ttYour choice :";
    getline(cin,choice);
    while (choice[0] !='1' && choice[0] !='2' &&choice[0] !='3' &&choice[0] !='4' &&choice[0] !='5' &&choice[0] !='6' &&choice[0] !='7' &&choice[0] !='8' &&choice[0] !='9' &&choice[0] !='0' )
       { 
       cout<<"ntt"<<choice<<" is invalid!";                           
       cout<<"nttEnter correct choice: ";
       getline(cin,choice);  
       }
    cout<<"ntt========================= nn";
}

//function 
void engine(string &choice,Rec &J,fstream &infile,fstream &outfile,int SIZE,char fname[],char tname[])
{
 switch (choice[0]){
 case '1':
      {
      cout<<"Executing number "<<choice<<":"<<"Open/check filen"<<endl;
      openFile(fname);
      break;
      } 

 case '2':
      {
      cout<<"Executing number "<<choice<<":"<<"Add recordsn"<<endl;
      addRec(J,fname);
      break;
      } 

 case '3':
      {
      cout<<"Executing number "<<choice<<":"<<"Append recordsn"<<endl;
      appRec(J,outfile,fname);
      break;
      } 

 case '4':
      {
      cout<<"Executing number "<<choice<<":"<<"Search for a recordn"<<endl;
      srcRec(J,infile,fname);
      break;
      } 

 case '5':
      {
      cout<<"Executing number "<<choice<<":"<<"Delete a recordn"<<endl;
      delRec(J,infile, outfile,fname,tname);
      break;
      } 
 case '6':
      {
      cout<<"Executing number "<<choice<<":"<<"Delete all recordsn"<<endl;
      delAll(fname);
      break;
      } 

 case '7':
      {
      cout<<"Executing number "<<choice<<":"<<"Modify a recordn"<<endl;
      modRec(J,outfile,fname);
      break;
      } 
case '8':
      {
      cout<<"Executing number "<<choice<<":"<<"List all recordsn"<<endl;
      listAll(J,infile,fname);
      break;
      } 
      case '9':
      {
      cout<<"Executing number "<<choice<<":"<<"Sort all recordsn"<<endl;
      sort();
      break;
      } 

default:exit(0); 
}
}   
//function 
void openFile(char fname[])
{
 cout<<"nOpening file"<<fname<<"..."<<endl;
 //confirm if file exists and opens
 fstream infile;
 fstream outfile;

 infile.open(fname,ios::in|ios::binary);
 if (infile.is_open())
 {
                     cout<<"File "<<fname<<" exists, and was opened succesfully.";
 }

 infile.close();

 //if fail ask to create
 if (infile.fail())
 {
     cout<<"File does not exist. Create? [Y]/[N]";
     char ch;
     cin>>ch;
     cin.ignore(numeric_limits<streamsize>::max(), 'n');
     //if yes then create file
     if(ch=='y'|| ch=='Y')
     outfile.open(fname,ios::out| ios::binary);
     //if not created display error
     if (outfile.fail())
        {
                      cout<<"Error: File not created"; 
        }                             
     //else confirm creation of file
     cout<<"File "<<fname<<" has been created.nn";
     outfile.close();
 }
}   
//function 
void addRec(Rec&J,char fname[])
{
     fstream outfile;
    outfile.open(fname,ios::out|ios::binary|ios::app);
    char another[10];

    do
    {    
        cout<<"Please enter ID number :";
        cin>>J.id;
        cin.ignore(numeric_limits<streamsize>::max(), 'n');
        cout<<"nPlease enter first name: ";
        cin.getline(J.fname,SIZE);
        cout<<"nPlease enter lastname: ";
        cin.getline(J.lname,SIZE);
        outfile.write((char*) &J, sizeof(J));
        cout<<"Add another record:[Y]/[N] ";
        cin.get(another[0]);
        cin.ignore(numeric_limits<streamsize>::max(), 'n');
     } while(another[0]=='y'||another[0]=='Y');
    cout<<"exiting to main menu.."<<endl;

}   
//function 
void delAll(char fname[])
{
 fstream outfile;
     cout<<"n------------------n"<<endl;
     cout<<"nDelete all records"<<fname<<"..."<<endl;
     cout<<"nAre you sure you want to delete all records in "<<fname<<" [Y]/[Any key for exit]?"<<endl;
     char ch;
     cin>>ch;
     cin.ignore(numeric_limits<streamsize>::max(), 'n');
     if(ch=='y'||ch=='Y')
     {
                         outfile.open(fname,ios::out|ios::binary|ios::trunc);
                         outfile.close();
     }

     else {cout<<"nExiting to main menu..."<<endl;}
}   
//function 
void listAll(Rec&J,fstream &infile,char fname[])
{
    infile.clear();                      
    infile.open(fname,ios::in|ios::binary);
    infile.read((char*)&J,sizeof(J)); 
    cout<<"|=======================================================|"<<endl;
    cout<<"| #     | ID       | FIRST         | LAST               |"<<endl;
    cout<<"|=======================================================|"<<endl;
        int count=1;
        while(!infile.eof())
        {
         cout<<"| "<<setw(6)<<left<<count<<left<<"| "<<setw(9)<<J.id<<"| ";
         cout<<left<<setw(14)<<J.fname<<"| ";
         cout<<left<<setw(19)<<J.lname<<"|"<<endl;
         infile.read((char*)&J,sizeof(J));
         count=count+1;
         cout<<"|-------------------------------------------------------|"<<endl;
        }
    infile.close();
}

//function 
void appRec(Rec &J,fstream &outfile, char fname[])
{
        outfile.open(fname,ios::out|ios::binary|ios::app);
        outfile.clear();        
        cout<<"Please enter ID number :";
        cin>>J.id;
        cin.ignore(numeric_limits<streamsize>::max(), 'n');
        cout<<"nPlease enter first name: ";
        cin.getline(J.fname,SIZE);
        cout<<"nPlease enter lastname: ";
        cin.getline(J.lname,SIZE);
        outfile.write((char*) &J, sizeof(J));
        outfile.close();

}
//----------------------------------------------------
void delRec(Rec&s,fstream &infile, fstream &outfile,char fname[],char tname[])
{
int current, request=1;
infile.open("c:/solident.dat",ios::in|ios::out|ios::binary);
if (!infile.is_open())
    cout << "infile not openn";
outfile.open("c:/temp.dat",ios::out|ios::binary|ios::trunc);
if (!outfile.is_open())
    cout << "outfile not openn";
for (;;)
{
    infile.read((char*)&s, sizeof s);
    if (infile.eof())
        break;
    current = s.id; 
    if (current != request)
        outfile.write((char*)&s, sizeof s);
}
infile.close();
outfile.close();

infile.open("c:/temp.dat)",ios::in|ios::binary);
outfile.open("c:/solident.dat)", ios::out|ios::binary|ios::trunc);
for (;;)
{
    infile.read((char*)&s, sizeof (s));
    if (infile.eof())
        break;
    outfile.write((char*)&s, sizeof (s));
}

infile.close();
outfile.close();

}
void srcRec(Rec&Job,fstream &infile,char fname[])
{
    cout << "Allowing the user to open a specific record.n";
    infile.open(fname, ios::in | ios::binary) ;
    if(infile.fail())
    {
        cout << "Could not access file.n";
    }
    else
    {
        int position;   //user's position
        //gets user's position
        cout << "Please the record you would like to read: ";
        cin >> position;
        //ignore luki
        cin.ignore(numeric_limits<streamsize>::max(), 'n');
        //find the specific record, read it, and display it
        infile.seekp((position - 1)*sizeof(Job));
        infile.read((char*) &Job, sizeof(Job));
    cout<<"|===============================================|"<<endl;
    cout<<"| ID       | FIRST         | LAST               |"<<endl;
    cout<<"|===============================================|"<<endl;
    cout<<left<<"| "<<setw(9)<<Job.id<<"| ";
    cout<<left<<setw(14)<<Job.fname<<"| ";
    cout<<left<<setw(19)<<Job.lname<<"|"<<endl; 
    }
    //clears and closes the file
    infile.clear();
    infile.close();
}

void modRec(Rec &J,fstream &outfile, char fname[])
{
    int position,   //user's position
        cntr = 0;   //marks the current record within the file
    cout << "Modifying a record.n";
    //open the two files
    outfile.open(fname, ios::out | ios::in | ios::binary);
    //get the user's desired position
    cout << "please enter the record you would like to modify: ";
    cin >> position;
    cin.ignore(numeric_limits<streamsize>::max(), 'n');
    cout << endl;
    if(outfile.fail())
    {
        cout << "File could not be read.n";
    }
    else
    {
        //find the desired record
        outfile.seekp((position - 1)*(sizeof(J)));
        //get the user's modification
        cout<<"Please enter ID number :";
        cin>>J.id;
        cin.ignore(numeric_limits<streamsize>::max(), 'n');
        cout<<"nPlease enter first name: ";
        cin.getline(J.fname,SIZE);
        cout<<"nPlease enter lastname: ";
        cin.getline(J.lname,SIZE);
        //write over the desired record
        outfile.write((char*) &J, sizeof(J));
    }
    //closes the files
    outfile.close();
}

void sort()
{
    int StructureSize, Idx1, Idx2;
    FILE * binaryFile;
    binaryFile = fopen("c:/solident.dat","rb+");
    Rec Index, IndexTemp;
    StructureSize = sizeof(Index);
    fseek(binaryFile, 0, SEEK_END);
    int fileSize = ftell(binaryFile);
    rewind(binaryFile);

    for (Idx1 = 0; Idx1 < fileSize; Idx1 += StructureSize)
    {
        for (Idx2 = 0; Idx2 < fileSize - StructureSize; Idx2 += StructureSize)
        {
            fread(&Index, StructureSize, 1, binaryFile);
            fread(&IndexTemp, StructureSize, 1, binaryFile);
            if (Index.id > IndexTemp.id)
            {
                fseek(binaryFile, -(StructureSize * 2), SEEK_CUR);
                fwrite(&IndexTemp, StructureSize, 1, binaryFile);
                fwrite(&Index, StructureSize, 1, binaryFile);
                fseek(binaryFile, -StructureSize, SEEK_CUR);
            }
            else
            {
                fseek(binaryFile, -StructureSize, SEEK_CUR);
            }
        }
        rewind(binaryFile);
    }
    fclose(binaryFile);
}

我不知道,这段代码似乎有一些问题。这只是其中之一

int request=1,current;
...
while (!infile.eof())
{    
      s.id=current; 
      if (current!=request)

在这段代码中,您没有给current一个值,但您仍然在使用该变量。这是一个未初始化的变量,这是你的代码不能工作的原因之一。

我想知道你是否打算写

      current=s.id; 

?这样就更有意义了。

尝试使用如下循环读取文件

infile.open("c:/solident.dat",ios::in|ios::out|ios::binary);
if (!infile.is_open())
    cout << "infile not openn";
outfile.open("c:/temp.dat",ios::out|ios::binary|ios::trunc);
if (!outfile.is_open())
    cout << "outfile not openn";
for (;;)
{
    infile.read((char*)&s, sizeof s);
    if (infile.eof())
        break;
    current = s.id; 
    if (current != request)
        outfile.write((char*)&s, sizeof s);
}
infile.close();
outfile.close();

如果我是你,我就不会用fail()。我认为用它来检测真正的读写失败是极不可能的。这更有可能是文件结束错误,或者打开文件失败。

@john .谢谢!第一部分是有效的,但仍在尝试Rename (tempname,destination)不起作用:(dest文件存在)

虽然temp.dat文件现在包含减去删除的记录,但输出不会写入solident.dat文件(它保持不变)

//所以我尝试从文件中读取每条记录,并将每条记录写入dest文件:

infile.open("c:/temp.dat)",ios::in|ios::binary);
outfile.open("c:/solident.dat)", ios::out|ios::binary|ios::trunc);
infile.read((char*)&s, sizeof s);
for (;;) 
{
if (infile.eof())
    break;
infile.read((char *)&s, sizeof (s));
outfile.write((char*)&s, sizeof (s));

}

infile.close ();

outfile.close ();

我的理解是,outfile和inffile非常简单:fstream。打开,关闭,清晰,它应该工作(我想)。似乎我错过了一些重要的东西,因为程序中简单的delete二进制结构函数似乎是命中注定的,我已经绕了几天了:它的一部分工作,然后我添加了几行代码,要么函数失败,要么整个程序失败。我倾向于将其归咎于编译器或devc++:),但我确信它必须是无效的代码!

谢谢你的帮助!