C語言中將結構體寫入檔案

2021-07-23 17:50:16 字數 3212 閱讀 5290

可以使用fwrite()將乙個結構體寫入檔案:

fwrite(&some_struct,sizeof somestruct,1,fp);

對應的fread函式可以再把它讀出來,此處fwrite受到乙個結構的指標並把這個結構的記憶體映像作為位元組流寫入檔案。sizeof操作符計算出結構占用的位元組數。

但是這樣用記憶體映像寫出的資料檔案卻是不能夠移植的,尤其是當結構中包含浮點成員或指標的時候。結構的記憶體布局跟機器和編譯器都有關。不同的編譯器可能使用不同數量的填充位,不同機器上基本型別的大小和位元組順序也不盡相同。因此,作為記憶體映像寫出的結構在別的機器上(甚至是被別的編譯器編譯之後)不一定能被讀回來。

同時注意如果結構包含任何指標(char*字串或指向其他資料結構的指標),則只有指標值會被寫入檔案。當它們再次被讀回來的時候可能已經失效。最後為了廣泛的可移植性,你必需用「b」標誌開啟檔案。

讀寫結構體的程式如下:

將結構體寫入檔案:

#include #include typedef struct st;

int main(void)

printf("sa:c=%c,h=%d,n=%d,m=%d,f=%f,d1=%f,s=%s,d2=%f\n",sa.c,sa.h,sa.n,sa.m,sa.f,sa.d1,sa.s,sa.d2);

printf("sizeof(sa)=%d:&c=%x,&h=%x,&n=%x,&m=%x,&f=%x,&d1=%x,&s=%x,&d2=%x\n",sizeof(sa),&sa.c,&sa.h,&sa.n,&sa.m,&sa.f,&sa.d1,&sa.s,&sa.d2);

fwrite(&sa,sizeof(sa),1,fp);

rewind(fp);

fread(&sb,sizeof(sb),1,fp);

printf("sb:c=%c,h=%d,n=%d,m=%d,f=%f,d1=%f,s=%s,d2=%f\n",sb.c,sb.h,sb.n,sb.m,sb.f,sb.d1,sb.s,sb.d2);

fclose(fp);

return 0;

}

從檔案中讀出結構體:

#include #include typedef struct st;

int main(void)

fread(&sb,sizeof(sb),1,fp);

printf("sb:c=%c,h=%d,n=%d,m=%d,f=%f,d1=%f,s=%s,d2=%f\n",sb.c,sb.h,sb.n,sb.m,sb.f,sb.d1,sb.s,sb.d2);

printf("sizeof(sb)=%d:&c=%x,&h=%x,&n=%x,&m=%x,&f=%x,&d1=%x,&s=%x,&d2=%x\n",sizeof(sb),&sb.c,&sb.h,&sb.n,&sb.m,&sb.f,&sb.d1,&sb.s,&sb.d2);

fclose(fp);

return 0;

}

在linux平台下的gcc編譯器進行編譯後的結果如下:

首先是結構體寫入檔案:

sa:c=k,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000

sizeof(sa)=40:&c=bfb98a10,&h=bfb98a14,&n=bfb98a18,&m=bfb98a1c,&f=bfb98a20,&d1=bfb98a24,&s=bfb98a2c,&d2=bfb98a30

sb:c=k,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000

從檔案中讀出結構體:

sb:c=k,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=���o��,d2=33.637000

sizeof(sb)=40:&c=bfbc9964,&h=bfbc9968,&n=bfbc996c,&m=bfbc9970,&f=bfbc9974,&d1=bfbc9978,&s=bfbc9980,&d2=bfbc9984

在windows xp 平台下利用visual c++編譯器編譯後結果如下:

寫入結構體: 

sa:c=k,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000

sizeof(sa)=48:&c=12ff28,&h=12ff2c,&n=12ff30,&m=12ff34,&f=12ff38,&d1=12ff40,&s=12ff48,&d2=12ff50

sb:c=k,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=abcdefg,d2=33.637000

讀出結構體:

sb:c=k,h=-3,n=20,m=100000000,f=33.320000,d1=78.572000,s=e,d2=33.637000

sizeof(sb)=48:&c=12ff28,&h=12ff2c,&n=12ff30,&m=12ff34,&f=12ff38,&d1=12ff40,&s=12

從上面的結果我們可以得到如下幾個結論:

1. 如果結構體中含有指標,是很容易出問題的,從上面的結果中(高亮)部分可以看到字串的輸出結果是不一樣的,這說明,在進行寫入檔案的時候,char*所指向的字串沒有寫入檔案,只是將指標寫入,當從檔案中讀出結構體,再次得到這個指標的時候,由於程式執行的記憶體位置變化,所以原來指標所指向的內容也變了,所以輸出也變了。

2. 還有乙個比較重要的是結構體的記憶體對其問題(之前也討論過)。可以看到,不同的編譯器採取的方式是不一樣的。 gcc中的結構體大小為40位元組,而vc下是48個位元組。

並且gcc下,結構體內存的起始位置是4的倍數,而vc中是8的倍數。這是因為,結構體的起始位址與其中所包含的擁有最多位元組的型別有關。之前也說過,因為gcc的處理方式是如果結構體內有超過4個位元組的型別,那麼結構體起始位置以4的倍數開始, 而vc中是以最大位元組數的為準。

ps:4的倍數就是位址的最低兩位是00,8的倍數就是位址最低三位為000

然後我分別在linux下讀入winxp寫的結構體檔案和在winxp下讀入linux下寫的結構體檔案,兩個平台下的程式都崩潰了。

C語言中將結構體寫入並讀取檔案

include include include typedef struct st int main void printf sa c c,str s,s s,h d n sa.c,sa.str,sa.s,sa.h printf sizeof sa d c x,str x,s x,h x n siz...

C語言中結構體

struct oursvoid main struct ours o2 01 結構體整體直接賦值的時候,即使字串也可以直接賦值 o1.str o2.str 錯誤,字串不能直接賦值 字串拷貝的方式 sprintf o1.str,02.str strcpy o1.str,o2.str 3.1 第一種情況...

C語言中的結構體

在 c語言中,結構體 struct 指的是一種資料結構,是c語言中聚合資料型別 aggregate data type 的一類。結構體可以被宣告為 變數 指標或 陣列等,用以實現較複雜的 資料結構。結構體同時也是一些元素的集合,這些元素稱為結構體的成員 member 且這些成員可以為不同的型別,成員...