将空白记录写入二进制文件时的无限循环

时间:2014-01-25 14:54:14

标签: c++ binaryfiles

以下短程序的目的是搜索特定列车(其编号从用户接受)的二进制文件(包含不同列车的详细信息),然后在该位置重写空白记录。

也就是说,我希望'删除'那条火车记录。

问题是程序进入无限循环并重复将空白记录写入二进制文件,从而导致创建一个巨大的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'结构的字节大小)!知道为什么会这样吗?

1 个答案:

答案 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();
}