10 文件

文件

1、文件基本概念

C程序把文件分为ASCII文件二进制文件,ASCII文件又称文本文件,二进制文件和文本文件(也称ASCII码文件)二进制文件中,数值型数据是以二进制形式存储的,

而在文本文件中,则是将数值型数据的每一位数字作为一个字符以其ASCII码的形式存储,因此,文本文件中的每一位数字都单独占用一个字节的存储空间,

而二进制文件则是把整个数字作为一个二进制数存储的,并非数值的每一位数字都占用单独的存储空间,无论一个C语言文件的内容是什么,

它一律把数据看成是字节构成的序列,即字节流,对文件的存取也是以字节为单位的,输入/输出的的数据流仅受程序控制而不受物理符号(如回车换行符)的控制,所以说C语言文件为流式文件

C语言的文件存取有两种方式:顺序存取随机存取

需要理解的知识点包括

  1. 数据流
  2. 缓冲区
  3. 文件类型
  4. 文件存取方式

数据流:

指程序与数据的交互是以流的形式进行的。进行C语言文件的存取时,都会先进行“打开文件”操作,这个操作就是在打开数据流,而“关闭文件”操作就是关闭数据流。

缓冲区(Buffer):

指在程序执行时,所提供的额外内存,可用来暂时存放做准备执行的数据。它的设置是为了提高存取效率,因为内存的存取速度比磁盘驱动器快得多。

C语言中带缓冲区的文件处理:

C语言的文件处理功能依据系统是否设置“缓冲区”分为两种:一种是设置缓冲区,另一种是不设置缓冲区。由于不设置缓冲区的文件处理方式,必须使用较低级的I/O函数(包含在头文件io.hfcntl.h中来直接对磁盘存取,这种方式的存取速度慢,并且由于不是C的标准函数,跨平台操作时容易出问题。下面只介绍第一种处理方式,即设置缓冲区的文件处理方式:

当使用标准I/O函数(包含在头文件stdio.h中时,系统会自动设置缓冲区,并通过数据流来读写文件。当进行文件读取时,不会直接对磁盘进行读取,而是先打开数据流,将磁盘上的文件信息拷贝到缓冲区内,然后程序再从缓冲区中读取所需数据,如下图所示:

事实上,当写入文件时,并不会马上写入磁盘中,而是先写入缓冲区,只有在缓冲区已满或“关闭文件”时,才会将数据写入磁盘,如下图所示。

文件类型:

分为文本文件二进制文件两种。

文本文件是以字符编码的方式进行保存的。二进制文件将内存中数据原封不至文件中,适用于非字符为主的数据。如果以记事本打开,只会看到一堆乱码。

其实,除了文本文件外,所有的数据都可以算是二进制文件。二进制文件的优点在于存取速度快,占用空间小,以及可随机存取数据。

文件存取方式:

包括顺序存取方式和随机存取方式两种。

顺序读取也就是从上往下,一笔一笔读取文件的内容。保存数据时,将数据附加在文件的末尾。这种存取方式常用于文本文件,而被存取的文件则称为顺序文件。

随机存取方式多半以二进制文件为主。它会以一个完整的单位来进行数据的读取和写入,通常以结构为单位。

文本文件操作

C语言中主要通过标准I/O函数来对文本文件进行处理。相关的操作包括打开、读写、关闭与设置缓冲区。
相关的存取函数有:fopen(), fclose(), fgetc(), fputc(), fgets(), fputs(),fprintf(), fscanf()等。

注意:应提前建立一个.text文本文件,放到与.c文件同一个文件夹中fopen() 打开文件函数 (成功打开后指向该流的文件指针就会被返回,失败返回NULL)fclose() 关闭文件函数

文件的使用方式和含义

打开方式含义指定文件不存在时指定文件存在时
r只读方式打开文本文件出错正常打开
w只写方式打开文本文件建立新文件文件原有内容丢失
a追加方式打开文本文件建立新文件在原有内容末尾追加

r+

读/写方式打开文本文件出错正常打开
w+读/写方式创建新的文本文件建立新文件文件原有内容丢失
a+读/追加方式建立新的文本文件建立新文件在原有内容末尾追加
rb只读方式打开二进制文件出错正常打开
wb只写方式打开二进制文件建立新文件文件原有内容丢失
ab追加方式打开二进制文件建立新文件在原有内容末尾添加
rb+

读/写方式打开二进制文件

出错正常打开
wb+读/写方式创建新的二进制文件建立新文件文件原有内容丢失
ab+读/追加方式创建新的二进制文件建立新文件在原有内容末尾追加

一、字符读写

1、字符写入文件函数 fputc

fputc函数的原型如下

int fputc( int c, FILE *fp );

参数说明
其中,c是要写入的字节,它虽被定义为整型,但只使用最低位的一字节,fp是文件指针。

fputc的功能:
将字节c输出至fp所指向的文件。如果成功,位置指针自动后 移1字节的位置,并且返回c;否则返回EOF。

2、从文件中读取字符 fgetc

fgetc函数的原型如下:

int fgetc( FILE *fp );

参数说明
其中fp为文件指针。

fgetc的功能:
fp所指向的文件中读取一个字节,如果成功则返回读取的字节,位置指针自动后移1字节的位置;否则返回EOF。

二、字符串的读写

1、字符串写入文件函数 fputs

fputs函数的原型如下

int fputs( const char *s, FILE *fp );

参数说明
其中,s是要写入的字符串,fp是文件指针。

fputs的功能
将字符串s输出至fp所指向的文件(不含'\0')。如果成功,位置指针自动后移,函数返回一个非负整数;否则返回EOF。

2、从文件中读取字符 fgets

fgets函数的原型如下

char *fgets( char *s, int n, FILE *fp );

参数说明
其中,s指向待赋值字符串的首地址,n是控制读取个数的参数,fp为文件指针。

fgets的功能
从位置指针开始读取 一行或n-1个字符,并存入s,存储时自动在字符串结尾加上'\0'。如果函数执行成功,位置指针自动后移,
并返回s的值,否则返回NULL。

三、块数据读写

所谓块读写,就是读写n块以m个字节为单位的二进制数据,可以是一个字符(一个字符为一字节,则块大小为1*1),可以是一个长度为n字符串(块大小1*n),可以是长度为n的整型数组(整型以4字节算,块大小4n),也可以是结构体等任意数据类型,并没有什么限制。

1、向文件中写入块数据fwrite

fwrite函数的原型如下:

size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );

参数说明:ptr:指向保存读写数据的内存的指针,它可以指向数组、变量、结构体等。size:表示每个数据块的字节数。count:表示要读写的数据块的块数。fp:表示文件指针。
理论上,每次读写 size*count 个字节的数据。

fwrite的功能:
从内存中的ptr指向的地址开始,将连续n*size字节的内容写入fp文件中。该函数的返回值是实际写入的数据块个数。

2、从文件中读取块数据fread

fread函数的原型如下

size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
//size_t 是在 stddef.h 头文件中使用 typedef 定义的数据类型,表示无符号整数,也即非负数,常用来表示数量。

参数说明
fwrite

fread的功能
从文件fp中,连续读取n*size字节的内容,并存入ptr指向的内存空间。该函数的返回值是实际读入的数据块个数。

四、格式化读写

格式化读写函数包括fprintffscanf两个函数,它们只用于文本文件的读写,不能用于二进制文件的读写。文本文件与二进制文件的区别下面注意点中有介绍。

1、格式化写入文件fprintf

fprintf函数的原型如下

int fprintf( FILE *fp, const char* format, 输出参数1, 输出参数2… );

参数说明:
其中,fp是文件指针,format为格式控制字符串,输出参数列表为待输出的数据。

fprintf的功能
根据指定的格式(format参数)发送数据(输出参数)到文件fp。

例:

#include <stdio.h>
  
int main()
{
    FILE *fp;
    fp = fopen("a.txt","w");
    int a = 10;
    double f = 11.11;
    fprintf(fp, "%d%lf", a, f);
    fclose(fp);
    return 0;
}
 
注意:fprintf()按格式输入到流,其用法和printf()相同,不过不是写到控制台,而是写到流罢了。注意的是
返回值为此次操作写入到文件的字节数。如int c =fprintf(fp, "%s %s %d %f", str1,str2, a, b) ;
假设str1:10字节;str2:10字节;a:2字节;b:8字节;则最终c为33,因为写入时不同的数据间自动加入一个空格。
2、从文件中格式化读取fscanf

fscanf函数的原型如下:

int fscanf( FILE *fp,  const char* format, 地址1,地址2… );

函数说明
其中,fp是文件指针,format为格式控制字符串,地址列表为输入数据的存放地址。

fscanf的功能
根据指定的格式(format参数)从文件fp中读取数据至内存(地址)。

例:

#include <stdio.h>
  
int main()
{
    FILE *fp;   
    fp = fopen("a.txt","r"); //需要创建a.txt文件,然后写入两个数据,空格隔开
    int i=0;
    double f=0;
    fscanf( fp, "%d%lf", &i, &f );
    fclose(fp);
    printf("%d\n%lf\n",i,f);
    return 0;
}

五、总结

1、fputcfgetc注意点

fputc 每次只能存一个字节,如果将整型、浮点型等数据类型写入文件(因为整型浮点型每个数据都需要好几个字节,由于平台不同不固定,具体自己查不列出),就会造成数据只截取最后一个字节导致数据出错;同理fgetc每次也只能读取一个字节。这时用 fprintffscanf 函数格式化读写比较合适。

fgetc 每次调用只能获取一个字节,如果是中文字符,utf8 编码会占用三个字节,因此要用 fgets 来读取。当然你不嫌累也可以用 fgetc 读三次,然后拼成一个中文字符。

2、fputsfgets注意点

fgets 有局限性,每次最多只能从文件中读取一行内容,因为 fgets 遇到换行符就结束读取。如果希望读取多行内容,需要使用 fread 函数;相应地写入函数为 fwrite

3、fwritefread注意点

fwritefread直接读写二进制文本。

常用文件函数及功能

分类函数名功能
打开文件fopen()打开文件。
关闭文件fclose()关闭文件。
文件定位fseek()
rewind()
ftell()
改变文件位置指针位置
使文件位置指针重新置于文件开头
返回文件位置指针的当前值
文件读写fgetc(),getc()
fputc(),putc()
fgets()
fputs()
getw()
putw()
fread()
fwrite()
fscanf(
fprintf()
从指定文件取得一个字符。
把字符输出到指定文件。
从指定文件读取字符串。
把字符串输出到指定文件。
从指定文件读取一个字(int型)。
把一个字(int型)输出到指定文件。
从指定文件中读取数据项。
把数据项写到指定文件。
从指定文件按格式输入数据。
按指定格式将数据写到指定文件中。
文件状态feof()
ferror()
clearerr()
若到文件末尾,函数值为“真”(非0)。
若对文件操作出错,函数值为“真”(非0)。
使ferror和feof函数值置零。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值