關於C之二進位制模式與文字模式

2021-09-29 07:31:19 字數 3346 閱讀 6658

用二進位制模式開啟乙個檔案的時候,檔案本身的內容和你編寫程式時用函式讀到的內容完全相同(或者說和磁碟上的內容完全相同)。

實際上, 所有的資料都是以二進位制形式儲存的, 甚至連字元都以字元碼的二進位制表示來儲存。 如果檔案中的所有資料都被解釋成字元碼, 則稱該檔案包含文字資料。 如果部分或所有的資料都被解釋成二進位制形式的數值資料, 則稱該檔案包含二進位制資料( 另外, 用資料表示機器語言指令的檔案都是二進位制檔案) 。

但是如果用了文字模式,那麼作業系統在將檔案內容傳給上層程式(庫函式,或者是你的程式)時,或者上層程式通過作業系統向檔案寫入內容時,作業系統都會預先進行一層預處理(或者說轉義),具體過程依賴於作業系統的實現。在windows+vc下,最常見就是將回車符"\r\n"(沒有引號,且\作轉義符用,下同)解釋成"\n"(讀出時),將"\n"解釋成"\r\n"(寫入時)。而在linux下沒有這層轉換,這也是windows和linux文字檔案不通用的原因。比如乙個txt檔案在windows下,"\r\n"就當作乙個換行符讀取,而在linux下就當作乙個回車加換行讀取了。

下面用兩種方式開啟乙個檔案「file.dat",內容為"abc\r\ndef":

1.以文字方式開啟並讀取:

fp = fopen("file.dat","r");

while(fgetc(fp)!=eof);

得到的內容為:abc\ndef

2.以二進位制方式開啟並讀取:

fp = fopen("file.dat","rb");

while(fgetc(fp)!=eof);

得到的內容為:abc\r\ndef

可以看到兩種開啟方式,得到的內容不一致。

c的文字讀寫與二進位制讀寫的差別僅僅體現在回車換行符的處理上。文字方式寫時,每遇到乙個''\n''(0ah換行符),它將其換成''\r\n''(0d0ah,回車換行),然後再寫入檔案;當文字讀取時,它每遇到乙個''\r\n''將其反變化為''\n'',然後送到讀緩衝區。正因為文字方式有''\n''--''\r\n''之間的轉換,其存在轉換耗時。二進位制讀寫時,其不存在任何轉換,直接將寫緩衝區中資料寫入檔案。

二進位制讀寫是將記憶體裡面的資料直接讀寫入文字中;而文字呢,則是先將資料轉換成字串,再寫入到文字中。

下面用乙個例子說明二者的差別:

#define _crt_secure_no_warnings

#define size 21

#include void write_to_binary_file();

void write_to_text_file();

void read_from_binary_file();

void read_from_text_file();

struct student ;

//使用二進位制寫入

void write_to_binary_file()

//文字格式寫入

void write_to_text_file()

//從二進位制讀取

void read_from_binary_file()

//從文字讀取

void read_from_text_file()

}int main()

binarycontent=111shine80.000000

textcontent=111shine80.000000

執行程式後在可執行檔案目錄下生成兩個檔案test_b.dat和test_t.dat:

對於二進位制模式int num=111,剛好等於16進製制的6f,1個位元組(因為111<127也可推出1個位元組);而對於文字模式111就變成字串"111"了,就是3個'1'(0x31表示),在文字檔案中寫成31,31,31用了3個位元組(因為"111"是三個字元表示也可推出3個位元組)。二者前面中間有一段相同的16進製制編碼7368696e65,對應的就是shine。而最後的是乙個浮點型別,對於文字模式,80.000000直接對應ascii碼的38302e303030303030,而二進位制模式是按國際標準ieee 754表示浮點數的(詳見:關於整數與浮點數二進位制表示

),保證精度。

test_t.dat是以文字資料資料儲存的,可以看到每個資料都被表示成了字元碼。 而test_b.dat是以二進位制資料儲存的,可以看到每個資料都被表示成了二進位制形式的數值資料,真實還原了結構體成員變數的資料型別值,int num=111=0x6f,char name=0x7368696e65(本就是字串這和文字模式下是一致的),float score=80.000000f。

文字模式下,由於每個資料都表示成1個字元碼,而1個字元占用1個位元組,所以字串的長度就是占用的位元組數,很浪費空間。二進位制模式下,int、long、float、double這樣的型別,分別也就佔4、4、4、8位元組(32位系統下),可成倍減少占用的空間,並且可以精確還原成相應的型別值。

下圖很直觀展示了兩種模式下的訪問區別:

例如:double num = 1./3.; fprintf(fp,"%f", num); 把num儲存為8個字元: 0.333333。 使用%.2f轉換說明將其儲存為4個字元:0.33,用%.12f轉換說明則將其儲存為 14 個字元:0.333333333333。改變轉換說明將改變儲存該值所需的空間數量,也會導致儲存不同的值。把num 儲存為 0.33 後,讀取檔案時就無法將其恢復為更高的精度。一般而言,fprintf()把數值轉換為字元資料,這種轉換可能會改變值。

為保證數值在儲存前後一致,最精確的做法是使用與計算機相同的位組合來儲存。因此,double 型別的值應該儲存在乙個 double 大小的單元中。如果以程式所用的表示法把資料儲存在檔案中,則稱以二進位制形式儲存資料。不存在從數值形式到字串的轉換過程。對於標準 i/o,fread()和 fwrite函式用於以二進位制形式處理資料。

二進位制和文字的用法很容易混淆。 ansi c和許多作業系統都識別兩種檔案格式: 二進位制和文字。 能以二進位制資料或文字資料形式儲存或讀取資訊。 可以用二進位制模式開啟文字格式的檔案, 可以把文字儲存在二進位制形式的檔案中。 可以呼叫 getc()拷貝包含二進位制資料的檔案。 然而, 一般而言,用二進位制模式在二進位制格式檔案中儲存二進位制資料。 類似地, 最常用的還是以文字格式開啟文字檔案中的文字資料( 通常文字處理器生成的檔案都是二進位制檔案, 因為這些檔案中包含了大量非文字資訊, 如字型和格式等)。

文字模式與二進位制模式

c語言是unix的產物,因此c對檔案的處理與unix環境適配。c把檔案看作是一系列連續的位元組,每個位元組都能被單獨讀取。但由於其他環境可能無法完全對應此模型,c提供兩種模型 文字模式和二進位制模式。關於文字模式和二進位制模式 所有檔案的內容 在磁碟上 都以二進位制表示。因為編碼方式不同,導致展現的...

文字模式 二進位制模式 文字檔案 二進位制檔案

這幾個概念很常見但是也容易搞混。前兩者是相反的意思,後兩者是一對。1.文字模式 textmode 和二進位制模式 binarymode 的 區別0.無論你用哪種語言進行程式設計,也無論你用哪個函式進行檔案操作 庫函式也好,直接作業系統api也好 最終的檔案開啟的操作都是由作業系統來進行的,因此各種語...

檔案開啟的文字模式和二進位制模式

首先要明白一點,就是無論你用哪種語言進行程式設計,也無論你用哪個函式進行檔案操作 庫函式也好,直接作業系統api也好 最終的檔案開啟的操作都是由作業系統來進行的,因此各種語言的情況從本質上來說都是相同的。用二進位制模式開啟乙個檔案的時候,檔案本身的內容和你編寫程式時用函式讀到的內容完全相同 或者說和...