这是整个计划。现在,删除功能不会写入临时文件。我将尝试将str数组更改为字符串,看看它是否有帮助。
该程序应该读取写入编辑搜索并使用结构对二进制文件进行排序。
#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<<"\n\n\n\t\t========================";
cout<<"\n\n\t\tMENU \n";
cout<<"\n\t\t========================\n\n";
cout<<"\t\t[1] Open/check file\n";
cout<<"\t\t[2] Add records\n";
cout<<"\t\t[3] Append records\n";
cout<<"\t\t[4] Search for a record\n";
cout<<"\t\t[5] Delete a record\n";
cout<<"\t\t[6] Delete all records\n";
cout<<"\t\t[7] Modify a record\n";
cout<<"\t\t[8] List all records\n";
cout<<"\t\t[9] Sort all records\n";
cout<<"\t\t[0] Exit\n";
cout<<"\n\t\t========================= \n";
cout<<"\t\tYour 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<<"\n\t\t"<<choice<<" is invalid!";
cout<<"\n\t\tEnter correct choice: ";
getline(cin,choice);
}
cout<<"\n\t\t========================= \n\n";
}
//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 file\n"<<endl;
openFile(fname);
break;
}
case '2':
{
cout<<"Executing number "<<choice<<":"<<"Add records\n"<<endl;
addRec(J,fname);
break;
}
case '3':
{
cout<<"Executing number "<<choice<<":"<<"Append records\n"<<endl;
appRec(J,outfile,fname);
break;
}
case '4':
{
cout<<"Executing number "<<choice<<":"<<"Search for a record\n"<<endl;
srcRec(J,infile,fname);
break;
}
case '5':
{
cout<<"Executing number "<<choice<<":"<<"Delete a record\n"<<endl;
delRec(J,infile, outfile,fname,tname);
break;
}
case '6':
{
cout<<"Executing number "<<choice<<":"<<"Delete all records\n"<<endl;
delAll(fname);
break;
}
case '7':
{
cout<<"Executing number "<<choice<<":"<<"Modify a record\n"<<endl;
modRec(J,outfile,fname);
break;
}
case '8':
{
cout<<"Executing number "<<choice<<":"<<"List all records\n"<<endl;
listAll(J,infile,fname);
break;
}
case '9':
{
cout<<"Executing number "<<choice<<":"<<"Sort all records\n"<<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.\n\n";
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 open\n";
outfile.open("c:/temp.dat",ios::out|ios::binary|ios::trunc);
if (!outfile.is_open())
cout << "outfile not open\n";
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);
}
答案 0 :(得分:0)
我不知道,这段代码似乎存在一些问题。这里只是其中一个
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 open\n";
outfile.open("c:/temp.dat",ios::out|ios::binary|ios::trunc);
if (!outfile.is_open())
cout << "outfile not open\n";
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()
。我认为用它来检测真正的读写失败是极不可能的。它更可能是文件错误结束或打开文件失败。
答案 1 :(得分:0)
@john。谢谢! 第一部分有效,但是尝试了 重命名(tempname,destination)不起作用: (目标文件存在)
虽然文件temp.dat现在包含记录减去已删除的记录,但输出不会写入solident.dat文件(它保持不变)
//所以我尝试从文件中读取每个rec并将每个记录写入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和infile非常简单:fstream.open,close,clear,它应该可以工作(我想)。虽然我错过了一些必不可少的东西,因为程序中的简单删除二进制结构函数似乎很受欢迎,而且我已经在圈子中转了几天:部分工作,然后我添加几行代码和一个函数失败或整个程序失败。我倾向于将它归咎于编译器或devc ++ :)但我确定它必须是无效的代码!
感谢您的帮助!