2015-05-04 57 views
2

我想輸出一個結構的數據到一個二進制文件,但沒有任何填充位之間的每個變量的信息。例如:如何輸出一個二進制文件在C中沒有填充位

struct s { 
    int i1; 
    short s1; 
    char c1; 
}; 
struct s example[2]; 

如果我使用fwrite(&example, sizeof(struct s), 2, file),二進制文件仍具有之間,例如,s1c1,也從c1i1 (of the 2nd struct)填充比特。

什麼是從輸出文件中刪除這些填充位的好方法?

謝謝!任何幫助表示讚賞

+0

查看接受的答案http://stackoverflow.com/questions/4306186/structure-padding-and-structure-packing – rslemos

+1

這是編譯器特定的。你正在使用哪種編譯器? –

+0

您可以遍歷數組,並分別寫入結構的每個元素。 – ace

回答

4

我只想建議手動讀取/寫入結構的成員分別。使用您的編譯器指令進行打包可能導致無法訪問的未對齊數據的低效率和可移植性問題。如果你必須處理字節順序,稍後當讀取操作分解爲字段成員而不是整個結構時很容易。

另一件事情,這更多地涉及到未來派的維護類型的關注,是你不希望你的序列化代碼或人們已經保存的文件到目前爲止打破,如果你有點改變結構(添加新的元素或甚至改變順序作爲緩存行優化,例如)。所以你可能會遇到很少的代碼,它比直接將結構的內存內容轉儲到文件中提供更多的呼吸空間,並且通常最終需要努力單獨序列化你的成員。

如果要概括的模式,減少樣板你寫的金額,你可以做這樣的事情作爲一個基本的例子來啓動和建立在:

struct Fields 
{ 
    int num; 
    void* ptrs[max_fields]; 
    int sizes[max_fields]; 
}; 

void field_push(struct Fields* fields, void* ptr, int size) 
{ 
    assert(fields->num < max_fields); 
    fields->ptrs[fields->num] = ptr; 
    fields->sizes[fields->num] = size; 
    ++fields->num; 
} 

struct Fields s_fields(struct s* inst) 
{ 
    struct Fields new_fields; 
    new_fields.num = 0; 

    field_push(&new_fields, &inst->i1, sizeof inst->i1); 
    field_push(&new_fields, &inst->s1, sizeof inst->s1); 
    field_push(&new_fields, &inst->c1, sizeof inst->c1); 

    return new_fields; 
} 

現在你可以使用這個Fields結構與通用功能來讀取和寫入任何結構的成員,就像這樣:

void write_fields(FILE* file, struct Fields* fields) 
{ 
    int j=0; 
    for (; j < fields->num; ++j) 
     fwrite(fields->ptrs[j], fields->sizes[j], 1, file); 
} 

這通常是一個容易一點比一些功能for_each_field種方法接受一個回調的工作。

現在你不用擔心,當你創造出一些新的結構,S約,是從一個實例定義一個函數來輸出struct Fields到,然後讓所有你寫與struct Fields工作,現在這方面的工作的一般功能新的S自動鍵入。

1

許多編譯器接受命令行參數,這意味着「包結構」。此外,許多接受編譯指示:

#pragma pack(1) 

其中1表示字節對齊,2表示16位字對齊,4表示32位字對齊等

0

爲了使獨立解決方案的平臺,您可以創建一個函數來逐個寫入每個字段的struct,然後調用該函數以根據需要編寫儘可能多的struct

int writeStruct(struct s* obj, size_t count, FILE* file) 
{ 
    size_t i = 0; 
    for (; i < count; ++i) 
    { 
     // Make sure to add error checking code. 
     fwrite(&(obj[i].i1), sizeof(obj[i].i1), 1, file); 
     fwrite(&(obj[i].s1), sizeof(obj[i].s1), 1, file); 
     fwrite(&(obj[i].c1), sizeof(obj[i].c1), 1, file); 
    } 

    // Return the number of structs written to file successfully. 
    return i; 
} 

用法:

struct s example[2]; 
writeStruct(s, 2, file); 
相關問題