今天我为大家讲讲c语言的文件操作,以下是我的见解,如有不对请多多指正。首先我们得了解什么是文件。
文件的定义:
磁盘上的文件是文件。 但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。像有.exe .obj 后缀的都是程序文件,而今天我要为大家详细讲述的是数据文件的读写。
使用文件的意义:
我举一个例子来说明吧,如果你用程序设计出一个通讯录。当程序退出时通讯录中你创建的数据所占的内存会被操作系统回收,进而数据丢失。但如果你创建出一个文件,并在程序退出时你将数据写在文件中,第二次打开程序的时候程序再在你写的文件中读取数据,就可实现数据的保存,实现数据的持久化。我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。
文件名:
列如:c:\code\test.txt
文件名是由存储路径+文件主干名+文件后缀名组成。路径分为绝对路径和相对路径。相对路径是由这个文件所在的路径引起的跟其它文件(或文件夹)的路径关系。绝对路径就是文件存储的某个确切的地点。
文件的打开与关闭:
是进行文件的读写之前,我们要先打开文件,那么如何打开文件呢?
我们要使用的是fopen函数,它的定义如下:
//打开文件
FILE* fopen(const char* filename, const char* mode);
第一个参数是文件名,第二个参数是文件的读取方式。c语言中的读取方式有很多:
如果只读文件但该文件不存在的时候,程序会报错。如果只写文件,就算文件不存在,它也会创建新的文件。注意:当用''w''时,每写一次文件就会清除上一次的全部内容!
该函数的返回名就要好好细说细说了。这里我们提到一个新的概念叫文件指针,它指向的是一个文件的信息区。该信息区存放的是文件名、文件的状态等,通过文件指针指向的文件信息就可以维护一个文件并对其进行相应的操作。FILE*本质上是一个结构体指针。
打开文件后就要关闭文件,不然可能会造成数据的数据的流失、计算机工作量大等问题。关闭文件我们用fclose函数。它的函数定义如下:
//关闭文件
int fclose ( FILE * stream );
参数就是打开文件后返回的地址。具体实现如下:
文件顺序的读写:
在理解文件的读写之前我们得先弄懂一些概念:
这种关系是以内存为第一人称。当你要读文件时,文件中的数据输入到内存中后,再在内存中进行查看(文件信息传给了我),这就是读,也是输入。当我要在文件中写数据时,就是内存中的数据输出到文件中,这便是写,也是输出。以下是有关读写文件名相关的函数:
fgetc和fputc是字符的读写。fgetc是读取文件中的一个字符,fputc是在文件中写一个字符。
目前我文本的内容是:abcd
那么该如何一次性读取所有数据呢?
当fget 为EOF时它就不读取数据或是数据全部读取完毕,所以我们可以用while循环的做法:
fgets和fputs针对的是字符串,是对文件进行字符串的读写。
int fputs( const char *string, FILE *stream )
它的使用如下:
char *fgets( char *string, int n, FILE *stream );
它的使用如下:
中间参数是需要读取字符的个数,那么我明明读取的是4个字符,为什么屏幕上显示的三个字符?其实并不是缺少,实际上是它把最后一个字符置成了'\0',原本是hell它把最后一个l变成'\0'后咱们就看不见啦!
前面的四个函数都是关于字符和字符串,不能应用于多格式化的数据,想要进行多格式化数据的读写,就需要fscanf和fprintf。fprintf该如何使用呢?
int fprintf( FILE *stream, const char *format [, argument ]...);
我们用结构体变量举个例子,它的使用方式如下:
fprintf与printf使用方法其实相仿,就是在printf参数的基础上增加了一个流(打开文件返回的文件指针)。fcanf该如何使用呢?
int fscanf( FILE *stream, const char *format [, argument ]... );
我们在上面的代码上进行改写,文件读取的内容依旧不变。
此时我们发现 最后一个数据不是85.500000而是0,这是为什么呢?当时我请教了我的老师,原来当我们在记事本中写入85.500000时,它是以文本的形式存在记事本中,而计算机想要读取其中的数据是不能检测出它的小数点后面的位数的。如果我们要读取一个小数,我们就需要用二进制的形式写入文本,再用二进制的形式读取出来就可以了。那么现在我们来谈谈二进制的输入与输出函数。首先是输出函数(用来写文件)fwrite的使用:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
我们依旧用之前的例子,看看这次到底能不能实现。
这次我们将之前的数据写入,当再次用记事本打开的时候,记事本出现了奇怪的符号,这是因为我们二进制的方式写入 ,而记事本使用文本的形式打开,所以才看不懂。现在我们再用二进制的形式读取文件,使用fread函数:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
现在来试试运用这个函数:
打印成功!