从二进制文件读取后,C ++ program.exe已停止工作

时间:2013-09-22 15:33:29

标签: c++

我已经创建了一个带有信息的类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 个答案:

答案 0 :(得分:4)

您的Flight班级包含std::string个成员。这些不是普通的旧数据类型,通常保存指向动态分配的内存的指针。您不能将您的课程作为一个单元进行阅读和编写,并希望std::string成员及其内容能够正确构建。这同样适用于TimeData成员,但您尚未展示他们的定义方式。

您需要查看正确的serialization

几个相关问题:

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

你必须重载operator&lt;&lt;和运算符&gt;&gt;对于Flight类,以及不是标准库的每个类成员。完成后你就会写:

fstream data;
Flight flight;
data >> flight;