1

我已经创建了一个类 Flight ,其信息以另一种方法存储在名为 data.txt 的二进制文件中。保存记录工作正常,但现在我在读取我保存的记录时遇到问题。它正在显示所有记录,直到文件(eof)结束。但是当记录显示​​完成时,会弹出一个错误,提示 Program.exe 已停止工作。

void Flight::ViewFlight(){
HANDLE hConsole;        //Console colors
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
fstream data;
Flight flight;
data.open("data.txt",ios::in | ios::binary);
if (data.fail())
{
    SetConsoleTextAttribute(hConsole, 12);
    cout<<"\n\nFlight data does not exist yet";
    cout<<"\n\nYou are being redirected to the Main Menu in 3 seconds\n\n";
    cout<<"3\n\n";
    Sleep(1000);
    cout<<"2\n\n";
    Sleep(1000);
    cout<<"1\n\n";
    Sleep(1000);
    cout<<"0\n\n";
    SetConsoleTextAttribute(hConsole, 15);
}
else{
    while(data.read((char*) &flight, sizeof(flight)))
    {   
        if(!data.eof())
        {
            SetConsoleTextAttribute(hConsole, 10);
            cout<<"\n\n----------- Record for "<<flight.flightid<<" -----------\n";
            SetConsoleTextAttribute(hConsole, 15);
            cout<<"\nFlight Number \t\t: "<<flight.flightnumber;
            cout<<"\nDeparture Airport\t: "<<flight.departAirport;
            cout<<"\nArrival Airport\t\t: "<<flight.arriveAirport;
            cout<<"\nDeparture Time\t\t: "<<flight.departTime.hour<<":"<<flight.departTime.minute;
            cout<<"\nDeparture Date\t\t: "<<flight.departDate.day<<"/"<<flight.departDate.month<<"/"<<flight.departDate.year;
            cout<<"\nPrice \t\t\t: RM "<<flight.price;
            cout<<"\nBusiness Class Seats\t: "<<flight.bseat;
            cout<<"\nFirst Class Seats\t: "<<flight.fseat;
            cout<<"\nEconomy Class Seats\t: "<<flight.totalseat;
            cout<<endl;
        }
    }
}
data.close();
}
4

4 回答 4

4

您的Flight班级包含std::string成员。这些不是普通的旧数据类型,通常保存指向动态分配的内存的指针。您不能将班级作为一个单元进行读写,并希望std::string成员及其内容能够正确构建。这同样适用于TimeandData成员,但您还没有展示它们是如何定义的。

您需要研究正确的序列化

几个相关问题:

于 2013-09-22T17:59:10.057 回答
0

飞行结构由指向动态分配的内存(堆)的其他类组成,例如string flightnumber;STL 字符串类,其中包含 char* 或 wchar*。如果将 Flight 对象保存为二进制缓冲区,它将仅保存指针。在加载对象时,您将在指针中获得内存地址,这是无效的。这就是您收到访问冲突异常的原因,这意味着您尝试访问未分配的内存。

顺便说一句,这是你得到 0xC0000005 的最好情况,在最坏的情况下,你只会访问为其他对象分配的内存,并在你的输出中得到垃圾。

您必须为 Flight 类以及每个非标准库的类成员重载 operator<< 和 operator>>。完成后,您只需编写:

fstream data;
Flight flight;
data >> flight;
于 2013-09-22T18:46:41.053 回答
0

循环似乎很好,您的文件可能有损坏的数据,可能是未终止的字符串,或者输入文件末尾可能有/是一些垃圾字符。验证循环中的所有 cout 语句的注释,并查看程序是否停止挂起。data.eof() 检查也是多余的,但它不应该挂起程序。

于 2013-09-22T16:59:46.287 回答
0

只是看看你的飞行类,你不能直接读入具有其他类对象的类。在您的情况下,字符串对象。您需要对流进行反序列化并自己初始化变量问题是当飞行被破坏时,它正在破坏那些不是正确构造的字符串对象的字符串对象。基本上首先将您的字符串与缓冲区分开,然后自己将它们一个一个分配给您的字符串变量。

于 2013-09-22T18:27:43.400 回答