讓我們考慮以下代碼:
#include <stdio.h>
int main(){
int val = 30;
FILE *file;
if(!(fopen("file.bin","wb"))){
fwrite(&val,sizeof(int),1,file);
fclose(file);
}
return 0;
}
我想知道如果我嘗試在架構中使用 fread 讀取此代碼生成的檔案,其中整數與生成檔案的架構中的整數大小不同,會發生什么情況。我認為結果將與此代碼中變數 val 的原始值不匹配。
如果這是真的,我們該如何處理這個問題?我們如何在 C 中生成可移植的二進制檔案?
uj5u.com熱心網友回復:
我想知道如果我嘗試在整數與生成檔案的架構中的整數大小不同的架構中讀取檔案會發生什么。
這絕對是一件值得擔心的好事。另一個大問題是位元組順序。
當你說
fwrite(&val, sizeof(int), 1, file);
您是在說,“int以二進制形式將其寫入檔案,使用與我機器記憶體中完全相同的表示形式:相同的大小,相同的位元組順序,相同的一切”。而且,是的,這意味著檔案格式本質上是由“它在我的機器上的表示”定義的,而不是以任何可移植的方式。
int但這不是以二進制形式寫入檔案的唯一方法。還有很多其他方式,具有不同程度的可移植性。我喜歡這樣做的方式很簡單:
putc((val >> 8) & 0xff, file); /* MSB */
putc( val & 0xff, file); /* LSB */
為簡單起見,我假設正在寫入的二進制格式使用兩個位元組(16 位)作為整數的磁盤版本,這意味著我假設int變數val永遠不會包含大于該數字的數字。
以這種方式撰寫,兩位元組整數以“大端”順序寫入,最重要的位元組在前。如果您想將二進制檔案格式定義為使用“小端”順序,則更改幾乎是微不足道的:
putc( val & 0xff, file); /* LSB */
putc((val >> 8) & 0xff, file); /* MSB */
您將使用一些看起來相似的代碼,包括呼叫getc和更多位移操作,在另一端讀回位元組并將它們重新組合成一個整數。這是小端版本:
val = getc(file);
val |= getc(file) << 8;
這些示例并不完美,并且只有在val是unsigned型別時才能保證對所有值都正常作業。為了處理有符號整數和大小不是兩個位元組的整數,我們可能會應用更多皺紋,但這應該可以幫助您入門。
另請參閱C FAQ 串列中的問題12.42和16.7。另請參閱一些在線 C 編程筆記的本章。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/505056.html
上一篇:洗掉文本檔案中的多行
