以下短程序的目的是搜索特定列车(其编号从用户接受)的二进制文件(包含不同列车的详细信息),然后在该位置重写空白记录。
也就是说,我希望'删除'那条火车记录。
问题是程序进入无限循环并重复将空白记录写入二进制文件,从而导致创建一个巨大的2 GB .dat文件。
#include<iostream.h>
#include<fstream.h>
struct train {
int train_no;
char train_name[50], source[20], dest[20];
int n_AC1, n_AC2, n_ACC, n_FC, n_SLC, n_SS; // variables for no of seats
train() { //default constructor
train_no = 0;
n_AC1=0, n_AC2=0, n_ACC=0, n_FC=0, n_SLC=0, n_SS=0;
strcpy(train_name, "/0");
strcpy(source, "/0");
strcpy(dest, "/0");
}
//member functions to accept and display the above values
};
void remove_train(fstream &f) {
train t, blank;
int tno, found = 0;
do {
cout<<"Enter the train no: ";
cin>>tno;
if(tno <=0)
cout<<"Invalid train number. Please re-enter."<<endl;
}
while(tno <=0);
f.seekg(0L, ios::beg);
f.read((char*)&t, sizeof(train));
while(!f.eof() && !found) {
if(t.train_no == tno) {
found = 1;
f.seekp(-sizeof(train), ios::cur);
f.write((char*)&blank, sizeof(train));
cout<<"Train number "<<tno<<" has been deleted!"<<endl;
}
else
f.read((char*)&t, sizeof(train));
}
if(found == 0)
cout<<"ERROR: train not found."<<endl;
}
int main() {
fstream f("Trains.dat", ios::binary | ios::in | ios::out);
remove_train(f);
cin.ignore();
cin.get();
}
当执行上述程序时,在我将列车编号输入为“1”之后,唯一可观察的输出是“已删除列车编号1”,之后程序进入上述无限循环。
这似乎不是一个孤立的问题;每当我试图向后移动一条记录时 然后在铁路预订项目的任何地方写一个空白记录,该代码是其中的一部分,同样的问题随之而来。例如,如果它是我想要覆盖的乘客记录,这是导致问题的相关代码片段:
f.seekp(-1L*sizeof(passenger), ios::cur);
f.write((char*)&p, sizeof(passenger));
MAJOR EDIT:当我用-110L替换-sizeof(train)时,问题得到解决( 'train'结构的字节大小)!知道为什么会这样吗?
答案 0 :(得分:0)
我必须说我在代码中发现错误而感到茫然。我已经运行了它的副本,它按预期工作。
有一些小错误(例如,如果你的数据文件不存在会失败)并且代码当然可以改进(你对f.eof()的使用有些尴尬),但没有什么可以解释你正在描述的行为。
这是我现在正在运行的确切版本。除了一些额外的代码来创建一个虚拟数据文件和一些调试输出,我认为没有任何差别。
也许您可以尝试编译它,看看它是否在您的环境中失败了?
#include<iostream>
#include<fstream>
#include <string.h>
using namespace std;
struct train {
int train_no;
char train_name[50], source[20], dest[20];
int n_AC1, n_AC2, n_ACC, n_FC, n_SLC, n_SS; // variables for no of seats
train() { //default constructor
train_no = 0;
n_AC1=0, n_AC2=0, n_ACC=0, n_FC=0, n_SLC=0, n_SS=0;
strcpy(train_name, "");
strcpy(source, "");
strcpy(dest, "");
}
//member functions to accept and display the above values
};
void remove_train(fstream &f) {
train t, blank;
int tno, found = 0;
do {
cout<<"Enter the train no: ";
cin>>tno;
if(tno <=0)
cout<<"Invalid train number. Please re-enter."<<endl;
}
while(tno <=0);
cout<<"deleting train "<<tno<<endl;
f.seekg(0L, ios::beg);
f.read((char*)&t, sizeof(train));
while(!f.eof() && !found) {
cout<<f.tellp()<<endl;
if(t.train_no == tno) {
found = 1;
f.seekp(-sizeof(train), ios::cur);
cout<<"delete "<<f.tellp()<<"/"<<f.tellg()<<endl;
f.write((char*)&blank, sizeof(train));
cout<<"Train number "<<tno<<" has been deleted!"<<endl;
}
else
{
cout<<"read "<<f.tellg()<<endl;
f.read((char*)&t, sizeof(train));
}
}
if(found == 0)
cout<<"ERROR: train not found."<<endl;
else
cout<<"done"<<endl;
}
void create_trains(int n)
{
fstream f("Trains.dat", ios::binary | ios::out);
train t;
for (int i = 1 ; i <= n ; i++)
{
t.train_no = i;
f.write((char*)&t, sizeof(train));
}
}
int main() {
create_trains (10);
fstream f("Trains.dat", ios::binary | ios::in | ios::out);
remove_train(f);
cin.ignore();
cin.get();
}