2013-09-22 31 views
0

我已經做了一個類的信息存儲在一個名爲data.txt的二進制文件中的另一種方法。保存記錄工作正常,但現在我'在閱讀我保存的記錄時遇到問題。它正在努力顯示所有記錄直到文件結尾(eof)。但是當記錄完成顯示時,會出現彈出錯誤,指出Program.exe已停止工作。從二進制文件中讀取C++ 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(); 
} 
+1

'Flight'的定義是相關的。 – molbdnilo

+0

http://codepad.org/LTSr5bCB –

+0

在調試器中運行您的程序,並查看它失敗的位置。 – user786653

回答

0

循環似乎罰款,你的文件可能已損壞的數據,可能是一個沒有結尾的字符串,也可以是有/是在輸入文件的末尾一些亂碼。驗證循環中所有cout語句的註釋,並查看程序是否停止。 也data.eof()檢查是多餘的,但它不應該掛起程序。

+0

嘗試評論所有的cout語句,仍然有相同的錯誤。 –

4

您的Flight類包含std::string成員。這些不是普通的舊數據類型,通常保存指向動態分配內存的指針。你不能讀寫班級,希望std::string成員及其內容能夠正確構建。這同樣適用於TimeData成員,但您尚未顯示它們是如何定義的。

您需要查看正確的serialization

的幾個相關問題:

+0

Time.h - http://codepad.org/CRSbIOLV Date.h - http://codepad.org/rP5EGArN –

+0

我現在很困惑。 –

+0

@JamesLeng:底線是你不能做一個'std :: string'對象的二進制文件轉儲。它是一個管理資源(內存)的類,只是寫入對象本身並不包含它指向的分配內存。你需要逐塊讀寫你的課程。在我的回答中添加了一些相關的SO問題。 – Blastfurnace

0

只是看了一下你的飛行類,你不能直接讀入一類具有其它類對象。在你的情況下,字符串對象。你需要deserliaze流並初始化你自己的變量 問題是當Flight被破壞時,它正在銷燬那些沒有正確構造字符串對象的字符串對象。 基本上先把你的字符串從你的緩衝區中分離出來,然後把它們一個接一個地分配給你的字符串變量。

0

飛行結構由指向動態分配的內存(堆)的其他類組成,例如string flightnumber;是STL字符串類,其內部具有char *或wchar *。 如果將Flight對象保存爲二進制緩衝區,它將僅保存指針。加載對象時,你會在指針中獲得內存地址,這是無效的。這就是你獲取訪問衝突異常的原因,這意味着你試圖訪問未分配的內存。

順便說一句,這是最好的情況下,你得到0xC0000005,在最壞的情況下,你只是訪問分配給其他對象的內存,並在你的輸出中得到垃圾。

您必須超載運營商< <和運營商>>的飛行類,每個不是標準庫的類成員。做完之後,你只需寫下:

fstream data; 
Flight flight; 
data >> flight;