2013-11-24 209 views
0

我正在寫一個C++程序,以二進制模式將數據寫入文件並從文件中讀取。 我正在寫一個對象並讀取一個對象。 我面臨的問題是,當我寫入文件並在沒有關閉程序的情況下讀取該文件時,它會運行文件。但是在程序終止執行後,註釋掉寫入代碼塊並嘗試讀取已經寫入的文件後,我得到了糟糕的輸出。讀取文件時C++數據損壞

我無法理解發生了什麼問題。

下面是代碼:

#include <fstream.h> 
#include <string.h> 

class Student{ 
    protected: 
     char *Name, *Sub_code; 
     int Roll; 
    public: 
     Student(){} 
}; 

class Details:private Student{ 
    private: 
     char *Sub_Name; 
     int internal_marks, external_marks; 
     /*Methods*/ 
     void setName(); 
     void setRoll(); 
     void setSubCode(); 
     void setSubName(); 
     void setInternalMarks(); 
     void setExternalMarks(); 
    public: 
     Details(){ 
     Name = new char[1]; 
      Sub_code = new char[1]; 
      Sub_Name = new char[1]; 
      Name[0] = '\0'; 
      Sub_code[0] = '\0'; 
      Sub_Name[0] = '\0'; 
      internal_marks = 0; 
      external_marks = 0; 
      Roll = 0; 
     } 
     void setDetails(); 
     void getDetails(); 
     static void writeDetails(Details detail); 
     static void readDetails(); 
}; 

void Details::setName(){ 
    cout<<"Enter Student Name : "; 
    char tmp[100]; 
    tmp[0] = '\0'; 
    cin>>tmp; 
    int len = strlen(tmp); 
    Name = new char[len]; 
    strcpy(Name,tmp); 
} 

void Details::setRoll(){ 
    cout<<"Enter Roll Number : "; 
    cin>>Roll; 
} 

void Details::setSubCode(){ 
    cout<<"Enter Subject Code : "; 
    char tmp[100]; 
    tmp[0] = '\0'; 
    cin>>tmp; 
    int len = strlen(tmp); 
    Sub_code = new char[len]; 
    strcpy(Sub_code,tmp); 
} 

void Details::setSubName(){ 
    cout<<"Enter Subject Name : "; 
    char tmp[100]; 
    tmp[0] = '\0'; 
    cin>>tmp; 
    int len = strlen(tmp); 
    Sub_Name = new char[len]; 
    strcpy(Sub_Name,tmp); 
} 

void Details::setInternalMarks(){ 
    cout<<"Enter internal marks : "; 
    cin>>internal_marks; 
} 

void Details::setExternalMarks(){ 
    cout<<"Enter external marks : "; 
    cin>>external_marks; 
} 

void Details::setDetails(){ 
    setName(); 
    setRoll(); 
    setSubCode(); 
    setSubName(); 
    setInternalMarks(); 
    setExternalMarks(); 
} 

void Details::getDetails(){ 
    cout<<Name<<"\t\t"; 
    cout<<Roll<<"\t\t"; 
    cout<<Sub_code<<"\t\t"; 
    cout<<Sub_Name<<"\t"; 
    cout<<internal_marks<<"\t"; 
    cout<<external_marks<<"\t\n"; 
} 

void Details::writeDetails(Details detail){ 
    ofstream os("StudentsRecord.dat", ios::binary|ios::ate); 
    os.write(reinterpret_cast <char *>(&detail),sizeof(detail)); 
    os.close(); 
} 

void Details::readDetails(){ 
    Details detail; 
    ifstream is("StudentsRecord.dat", ios::binary|ios::in|ios::beg); 
    cout<<"Name\tRoll\tSubject Code\tSubject Name\tInternal marks\tExternal Marks\n"; 
    while (is.read(reinterpret_cast<char *>(&detail), sizeof(detail))){ 
     detail.getDetails(); 
    } 
    is.close(); 
} 

int main(){ 
    Details y,x; 
    /*for(int i = 0; i < 2; i++){ 
     x.setDetails(); 
     Details::writeDetails(x); 
    }*/ 
    Details::readDetails(); 
    return 0; 
} 

在主(註釋的代碼)是用於在文件中寫入數據的塊。 這是我得到的輸出的示例屏幕截圖。 Screenshot of the output.

問候Priyabrata

回答

2

Detail類有char*內。當你把它寫入文件時,你會寫出字符串的實際指針地址,而不是實際的字符串。當你在相同的程序中讀回它時,它的工作原理是因爲數據仍然存在。

當你重新運行你的程序時,你會得到垃圾,因爲那個指針不是隨機的一塊內存。

你應該使用一個爲你做序列化的庫。這很難讓它正確。 看看https://code.google.com/p/protobuf/,但我確定還有其他的。

+0

我明白了原因,但是難以將protobuf整合到我的代碼中,再加上它在我的大學裏是不可接受的。我需要通過使用(如果存在)另一種方式來解決這個問題。 – Priyabrata

+0

@Priyabrata然後你需要設計一種方法來編碼你的結構中的所有指針。你需要確保寫入文件的是實際的數據(任何地方都沒有指針)。 Protobuffer只是實現這一目標的一個例子,但肯定不是唯一的方法。 – Sorin