2013-01-13 61 views
0
void updatebfile(char filename[MAX]) 
{ 

fstream writereadb; 

char cont='y'; 
char filenameb [MAX]; 
int i=1; 
int record; 

student s; 

strcpy(filenameb,filename); 
strcat(filenameb,".dat"); 

writereadb.open(filenameb,ios::in | ios::out | ios::binary ); 


cout<<"------------------------------" 
    <<endl; 

cout<<"Begin updating of binary file " 
    <<filenameb 
    <<endl 
    <<endl; 

cout<<"Information for student file" 
    <<endl 
    <<endl; 


while (writereadb.read (reinterpret_cast <char *>(&s), sizeof (s))) 
{ 

    cout<<i 
     <<'\t' 
     <<s.identity 
     <<" " 
     <<s.name 
     <<endl; 

    i++; 


} 

do 
{ 


cout<<endl 
    <<"Update record: "; 
cin>>record; 

cout<<endl 
    <<"Student id: "; 



writereadb.seekg ((record - 1) * sizeof(s), ios::beg);//problem is here 
writereadb.read (reinterpret_cast <char *>(&s), sizeof (s));//always reading last value 


cout<<s.identity 
    <<endl; 





cout<<"Update the name: "; 
cin>>s.name; 



writereadb.seekp((record-1)*sizeof(student),ios::beg); 
writereadb.write (reinterpret_cast <const char *>(&s), sizeof (s)); 

cout<<"Any more update (y/n) :"; 
cin>>cont; 

}while (cont=='y'); 

writereadb.close(); 







} 

我有這個簡單的功能,我想更新二進制文件。問題是我似乎無法設置獲取指針,我總是讀取二進制文件中的最後一個值,當我cout s.identity需要幫助調試簡單更新二進制文件功能

回答

2

您總是嘗試讀取一個條目,並只使用結果,如果成功(這是完全正確的)。如果它沒有成功,例如因爲它遇到EOF,流狀態將被設置爲「失敗」。這將導致讀取循環終止,但也會導致對該文件流的任何後續操作失敗,直到您顯式重置流狀態。因此,您需要在該循環後呼叫writereadb.clear()

一些更多的注意事項:

  • 傳遞一個char filename[MAX]不會傳遞一個數組的功能!相反,它與char* filename相同,即修改該參數將使其在調用函數中可見。使用std::string,使用它們的c_str()成員函數獲取fstream的指針。
  • 你沒有讀到最後一個值,你沒有閱讀它!你的代碼應該檢測到了。此外,它似乎讀取了最後一個值,因爲您正在重用臨時結構。一般來說,儘量保持變量範圍的大小是一個好主意。在函數的開頭聲明所有變量的習慣屬於舊時代(上個世紀),這是C代碼所必需的,而C++代碼則不然。在這種情況下,我甚至可以想象將整個程序分成兩個或三個功能。
  • 轉儲文件的結構在不同計算機之間是不可移植的,有時甚至不是同一臺計算機上的不同編譯器。出於這個原因,有多個序列化庫可以正確執行此操作。
+0

非常感謝,我花了2小時試圖調試它 – Computernerd