2012-05-14 120 views
0

我的問題是這樣的:我有一個名爲'Register'的類。它有一個名爲「trainName」的字符串屬性,它的制定者:字符串到二進制文件

class Register { 

private: 
    string trainName; 

public: 
    string getTrainName(); 
}; 

由於事實上,它是長,但我想使這個簡單。

在其他類中,我將幾個Register對象複製到一個二進制文件中,之前設置了trainName。

Register auxRegister = Register(); 
auxRegister.setName("name"); 

for(int i = 0; i < 10; i++) { 

    file.write(reinterpret_cast<char*>(&auxRegister),sizeof(Register)); 

} 

後來,我嘗試從二進制文件中檢索寄存器:

Register auxRegister = Register(); 

while(!file.eof()) { //I kwnow this is not right. Which is the right way? 

    file.read(reinterpret_cast<char*>(&auxRegister), sizeof(Register)); 
} 

它發生這是行不通的。事實上,寄存器確實有更多的屬性(它們是int),並且我可以檢索它們,但字符串並不是這種情況。

我做錯了什麼?在處理二進制文件和字符串時,我應該考慮一些事情嗎?

非常感謝。

回答

2

你不能這樣寫字符串,因爲它幾乎肯定包含指向一些結構體和其他二進制文件的指針,這些指針根本不能被序列化。 您需要編寫自己的序列化函數,並寫入字符串長度+字節(例如)或使用完整的庫,例如protobuf,這可以爲您解決序列化問題。

編輯:見普萊托裏安的答案。比我的要好得多(即使在編輯時分數較低)。

2

std::string類包含一個指向存儲字符串的緩衝區的指針(以及其他成員變量)。字符串緩衝區本身不是類的一部分。因此,寫出類的實例的內容不會起作用,因爲如果您這樣做,字符串將永遠不會成爲您轉儲到文件中的一部分。你需要獲得一個指向字符串的指針並寫入。

Register auxRegister = Register(); 
auxRegister.setName("name"); 
auto length = auxRegister.size(); 

for(int i = 0; i < 10; i++) { 
    file.write(auxRegister.c_str(), length); 
    // You'll need to multiply length by sizeof(CharType) if you 
    // use a wstring instead of string 
} 

稍後,要讀取字符串,您必須跟蹤寫入文件的字節數;或者可能從文件本身獲取該信息,具體取決於文件格式。

std::unique_ptr<char[]> buffer(new char[length + 1]); 
file.read(buffer, length); 

buffer[length] = '\0'; // NULL terminate the string 
Register auxRegister = Register(); 

auxRegister.setName(buffer);