# c语言中对二进制文件的操作函数


### 1、fopen 的用法


FILE * fopen(char *filename, char *mode);


函数参数:


1.filename:文件名,包括路径,如果不显式含有路径,则表示当前路径。例如,“D:\\f1.txt”表示 D 盘根目录下的文件 f1.txt 文件。“f2.doc”表示当前目录下的文件 f2.doc。


2.mode:文件打开模式,指出对该文件可进行的操作。



  r      只读     文件必须存在,否则打开失败                           


  w    只写     若文件存在,则清除原文件内容后写入;否则,新建文件后写入            


  a     追加只写  若文件存在,则位置指针移到文件末尾,在文件尾部追加写人,故该方式不 删除原        文件数据;若文件不存在,则打开失败


  r     读写    文件必须存在。在只读 r 的基础上加 '+' 表示增加可写的功能。下同     


  w    读写     新建一个文件,先向该文件中写人数据,然后可从该文件中读取数据          


  a    读写     在” a”模式的基础上,增加可读功能                      


  rb    二进制读  功能同模式”r”,区别:b表示以二进制模式打开。下同              


  wb   二进制写   功能同模式“w”。二进制模式                          


  ab    二进制追加 功能同模式”a”。二进制模式                          


  rb  二进制读写 功能同模式"r+”。二进制模式                         


  wb    二进制读写 功能同模式”w+”。二进制模式                         


  ab  二进制读写 功能同模式”a+”。二进制模式                         


## 2、判断文件是否结束


方法一:使用feof(文件指针)函数,用来判断文件是否结束  //文本文件和二进制文件都可用。


返回值为1,文件结束;


返回值为0,文件没有结束。


方法二:判断EOF(-1)标志 //仅适用于文本文件


因为文本文件中,数据是以ASCII码值形式存放的,而ASCII码值的范围是0-255,不会等于-1.


## 3、读写二进制文件函数




### 1)fread


fread(buffer,size,count,fp)


buffer:指针,表示内存中存储空间的首地址;


count:要读写的单元数


size:每单元的字节数


fp:文件指针。


从fp所指的文件中读count个单元,每个单元size个字节,到以buffer为起始地址的内存中


例如:


**int a[2];**


**fread(a,4,2,fp);**


### 2)fwrite


fwrite(buffer,size,count,fp)


buffer:指针,表示内存中存储空间的首地址;


count:要读写的单元数


size:每单元的字节数


fp:文件指针。


将以buffer为起始地址内存中的count个单元,每个单元size个字节写到fp所指的文件中。


例如:


**int a[2]={1,2};**


**fwrite(a,4,2,fp); 将以a为起始地址的内存中的2个单元,每单元4个字节,写到fp所指的文件中。**


## 4、文件定位函数


顺序存储的时候,对文件读写操作是从文件的开始位置进行的,


随机存取文件可以从从文件的任意位置进行操作的。


fopen的时候,文件位置指针指向文件的开头,第一个数据之前;


文件结束后,文件位置指针指向文件的结尾,最后一个数据之后。


对数据进行读操作,文件位置指针指向尚未读数据之前;


对数据进行写操作,文件位置指针指向刚写入的数据之后。


### 1)fseek(fp,offset,origin); 一般用于二进制文件,因为文本文件会发生字符转换,计算位置会发生混乱。


offset为以origin为几点,以字节为单位的偏移量;当offset为正整数,表示位置指针从指定的起始点向后移动,当offset为负整数的时候,表示位置指针从指定的起始点向前移动。


![image-20210918165134690](C:\Users\KYboi\AppData\Roaming\Typora\typora-user-images\image-20210918165134690.png)


返回到文件开头位置:


fseek(fp,0L,SEEK_SET);   //文件第一个数据之前?(指向文件第一数据)


返回到文件末尾位置:


fseek(fp,0L,SEEK_END);  //文件最后一个数据之后


### 2)ftell函数


获得文件当前位置指针的位置,并返回当前位置指针相对于文件开头的字节数。


ftell(文件指针)


例如:


计算文件的中总的字节数


fseek(fp,0L,SEEK_END);


long   size = ftell(fp);


### 3)rewind函数


rewind(fp);


使文件指针返回到文件开头位置。


等价于fseek(fp,0L,SEEK_SET);




#### 补充:


C 程序与文件的访问中,经常涉及换行操作。二进制文件与文本文件在换行规则上略有差别。


在 UNIX 和 Linux 系统中,无论是二进制文件还是文本文件,均是以单字节 LF(0x0A) 即作为文件中的换行符。


由于 C 语言是在 UNIX 系统上提出并发展起来的,故 C 语言中的换行规则与 UNIX 系统文件中的换行规则是一致的,使用 LF 即 '\n' 表示换行。因此 C 语言程序访问 UNIX/Linux 系统中的文件时,可直接访问,不需要转换。


而在 DOS/Windows 系统中,文本文件使用 ASCII 值为 13(0x0D) 的回车符 CR(Carriage-Return) 以及 ASCII 值为 10(0x0A) 的换行符 LF(Line-Feed) 这两个符号,即双字节 CR-LF(0x0D 0x0A) 的 'r'、'\n' 作为文本文件的换行符。与 C 语言程序中的换行符不一致。


因此,若使用 C 语言程序访问 DOS/Windows 系统中的文本文件,针对换行符的差异,就必须多一层转换。如果把 C 程序中数据以文本的方式写入文件时,需要把 C 程序中的 '\n' 转换为 'r' 和 '\n' 这两个字符后,再写入文本文件;当 C 程序以文本方式读取文本文件中的数据时,需要把文本文件中连续出现的两个字符 'r'、'\n' 转换为一个字符 '\n' 后,送给 C 程序。


说明:DOS/Windows 系统的文本文件中,回车 '\r' 和换行 '\n' 的含义如下:


- 回车'\r':表示光标回到该行的行首处。


- 换行'\n':表示光标从当前行该列位置移动到下一行对应的该列位置。