前言
本篇文章介紹一下C語言的文本模式和二進制模式
文本文件和二進制文件
從宏觀上看,無論是文本文件還是二進制文件,文件中保存的都是0和1的序列
,因為磁盤只有這兩種狀態。不同的文件只是對0、1序列的解釋不同,如果文件內容是以字符編碼的方式保存到文件中的
,無論是以哪種編碼方式,比如使用ascii編碼,unicode編碼都可以,這樣的文件就是文本文件,也就是文本文件中存在的是一個個字符。如果文件保存的是機器可以識別的數值在內存中的表示,或者是圖片、音頻等編碼的數據,那這種文件就是二進制文件,舉個簡單的例子,對于數字
int i=10000;
如果我們用文本方式保存該值,應該保存’1’、‘0’、‘0’、‘0’、'0’五個字符,但是如果以二進制表示呢,我們只需要保存i的二進制表示
00000000 00000000 00100111 00010000
按照小端法保存依此應該是00010000 00100111 00000000 00000000
C語言的文本模式和二進制模式
C語言之所以要區分文本模式和二進制模式,主要原因就是不同的平臺對文本文件的操作不一樣,看下面這段代碼:
#include <stdio.h>
int main(void)
{printf("\\r=%hhd,\\n=%hhd\n",'\r','\n');FILE* file = fopen("test.d", "w");fprintf(file, "A\nB");fclose(file);file = fopen("test.d", "rb");char ch=' ';while((ch=getc(file))!=EOF){printf("%c,%hhd\n",ch,ch);}fclose(file);return 0;
}
在mac上顯示結果如下:
\r=13,\n=10
A,65,10
B,66
在win上顯示結果如下:
\r=13,\n=10
A,65
,13,10
B,66
可以發現,在mac上以文本模式存儲換行符存儲的是\n(據說老版mac存的是\r),在windows系統上存儲的是\r\n,鑒于此,C標準針對文本模式讀取寫入換行符的時候進行了處理,讀取換行符的時候,統一轉換成\n,寫入換行符的時候,根據不同系統寫入不同的數據,比如windows就寫入\r\n,把上面的例子讀取文件從二進制模式修改為文本模式
#include <stdio.h>
int main(void)
{printf("\\r=%hhd,\\n=%hhd\n",'\r','\n');FILE* file = fopen("test.d", "w");fprintf(file, "A\nB");fclose(file);file = fopen("test.d", "r");char ch=' ';while((ch=getc(file))!=EOF){printf("%c,%hhd\n",ch,ch);}fclose(file);return 0;
}
在windows上執行結果如下:
\r=13,\n=10
A,65,10
B,66
可以發現\r\n轉換成了\n
還有一點需要注意,對于文本模式和二進制模式,我們使用ftell獲取字節數大小的時候
windows系統換行符算兩個字節
,不管文本模式還是二進制模式,mac系統換行符算一個字節- 對于windows系統,文本模式獲取的換行符為雖然算兩個字符,但是打印出來的都是\n
看下面的例子:
#include <stdio.h>
int main(void)
{printf("\\r=%hhd,\\n=%hhd\n", '\r', '\n');FILE* file = fopen("test.d", "r");fseek(file, 0, SEEK_END);long size = ftell(file);for (int i=1;i<=size;i++){fseek(file, -i, SEEK_END);printf("%hhd\n",getc(file));}printf("size:%ld\n", size);fclose(file);return 0;
}
在mac系統下,輸出的字節大小都是3,
在windows系統下,輸出的字節大小是4,文本模式輸出如下:
\r=13,\n=10
66
10
10
65
size:4
二進制模式輸出如下:
\r=13,\n=10
66
10
13
65
size:4
總結
我們一般使用二進制模式保存的數據都是我們定義好的數據結構數據,這種數據是不需要換行符這種東西的,基本是為了數據的安全或者更緊湊。我們自己負責數據的修改和解析
如果是為了顯示或者便于別人編輯的數據,建議保存成文本文件。