2010-04-24 79 views
0

我想使用fread()從文件讀取加密的結構數據。一旦我得到解密的結構字節,我想把它放回到這個結構中。結構到字節

struct data 
{ 
    std::string s1; 
    std::string s2; 
    std::string s3; 
    LONG l; 
}; 

你會如何將一個結構轉換爲可以從字節重建的字節?

+2

是串的std :: string?如果不是,那是什麼? – 2010-04-24 23:17:24

+0

戴夫, 這是混亂。你是說結構中的標識符'string'實際上是一個char *的typedef?這就是尼爾所要求的。 – zumalifeguard 2010-04-24 23:41:35

+0

一個問題是LONG數據類型沒有很好的定義......在一臺計算機上它可能是32位,在另一臺計算機上它可能是64位。除非數據永遠不會出現在單個計算機之外,否則最好使用int32_t或其他具有明確定義的位寬的類型。 – 2010-04-25 02:31:40

回答

1

問題是std::string不包含有問題的字節,它包含一個指針到您實際想要存儲的字節。您應該將每個字符串保存爲一個以null結尾的字符串,然後在該文件中保存一個很長的原始文件。

如果您正在尋找像.NET提供的「點擊式」序列化解決方案,那麼在C++中找不到您想要的內容。 Boost's serialization library可能會有所幫助,因爲它會爲您序列化一些標準庫對象,但您需要自己實現用於用戶定義的類。

0

對於一般情況,編寫一個函數來手動序列化結構中的所有成員,另一個函數通過依次反序列化所有成員來從字節流創建一個結構。你可以使用腳本來爲你生成這些函數(不幸的是,C++不支持像Java反射這樣的東西)。

你可以看看boost/serialization

+0

說服爲什麼這需要一個downvote! – Joshua 2010-04-25 01:15:59

+0

只有一個結構,這是打破了一個輪子上的蝴蝶,但我認爲它也不應該得到一個downvote太,因爲他寫了「的一般情況下」。 – 2010-04-25 01:23:36

1

我會做這樣的事情:

struct serialized_data { 
    size_t s1_offset; 
    size_t s2_offset; 
    size_t s3_offset; 
    long l; 
    char strings[1]; 
}; 

serialized_data* serialize (data d) { 
    serialized_data* s = malloc(sizeof(serialized_data) + d.s1.length() + d.s2.length() + d.s3.length() + 3); 
    s->s1_offset = 0; 
    s->s2_offset = d.s1.length() + 1; 
    s->s3_offset = s2_offset + d.s2.length() + 1; 
    s->l = d.l; 
    strcpy(s->strings, d.s1.c_str()); 
    strcpy(s->strings + s->s2_offset, d.s2.c_str()); 
    strcpy(s->strings + s->s3_offset, d.s3.c_str()); 

    return s; 
} 
+0

請記住處理有人通過反序列化代碼中的垃圾偏移量/長度的情況。 – 2010-04-25 00:03:19

0
struct data 
{ 
    std::string s1; 
    std::string s2; 
    std::string s3; 
    long l; 
}; 


int Write(FILE* file, const data* myData) 
{ 
    unsigned long length; 

    length = myData->s1.size(); 
    fwrite((void*) &length, sizeof(length), 1, file); 
    fwrite((void*) myData->s1.data(), length, 1, file); 
    ... // write the other strings and long here 
} 

int Read(FILE* file, data* myData) 
{ 
    unsigned long length; 
    char* buffer; 

    fread((void*) &length, sizeof(length), 1, file); 
    buffer = new char[length]; 
    length = fread(&buffer, length, 1, file); 
    myData.s1 = string(buffer, length); 
} 

當然,做錯誤檢查,什麼不能