文件的顺序读写:
文件操作函数有哪些呢?如下:
我们来了解一下这些函数。
文件的输入和输出流函数(顺序读写):
- 以下函数的头文件都为#include<stdio.h>
fgetc函数和fputc函数:
实际运用:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {//打开文件 //相对入径 FILE* pf=fopen("test.txt", "r"); //绝对入径 //FILE* pf=fopen("D:\\code\\code.txt", "w"); if (pf == NULL) {//fopen函数的返回值是file*的,可能会传回来空指针,所以要判断一下。 perror("fopen"); return 1; } // 写文件 fputc('a', pf); fputc('b', pf); fputc('c', pf); int i = 0; /*for (int i = 0; i < 26; i++) { fputc('a' + i, pf); }*/ //int ch = fgetc(pf); //printf("%c ", ch); /*for (int i = 0; i < 26; i++) { int ch = fgetc(pf); printf("%c ", ch); }*/ //结束文件 fclose(pf);//这个不会将pf设为空指针,我们要将pf设为空指针 pf = NULL; return 0; }
运行结果:
fgets和fputs函数:
如何运用:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { //打开文件 char*pf=fopen("test.txt", "r"); if (pf == NULL) { perror("fopen:"); return 1; } //写文件 char ch[20]="qqqq"; fgets(ch, 20, pf); printf("%s\n", ch); //关闭文件 fclose("test.txt"); pf = NULL; return 0; }
运行结果:
fputs函数我就不讲如何使用了,就是记得把fopen函数的r改为w。
fread函数和fwrite函数:
fread函数:
参数:
- ptr为指向大小至少为(size*count)字节的内存块的指针,转换为 void*。
- size为每个元素的大小。
- count为个数
- stream为文件指针。
用处:
- 从输入流中读取数据到内存到内存
- 流的位置指示器按读取的字节总数前进。
- 如果成功,读取的总字节数为(大小*计数)。
返回值
- 返回值为size_t类型。返回成功读取的元素总数。
- 如果此数字与 count 参数不同,则表示读取时发生读取错误或到达文件末尾。
- 如果大小或计数为零,则该函数返回零,并且 ptr 所指向的流状态和内容保持不变。
fwrite函数:
参数:
- ptr为指向指向要写入到文件的元素数组的指针。
- size为要写入的数组每个元素的内存大小。
- count为个数
- stream为文件指针
用处:
- 将元素数组从计算机(内存)写到文件。
- 流的位置指示器按写入的总字节数前进。
- 在内部,该函数将 ptr 所指向的指针解释为一个无符号 char 类型的(大小*计数)元素数组,并按顺序将它们写入输出流,就好像为每个字节调用了 fputc 一样。
返回值:
- 为size_t类型
- 如果成功,就返回写入元素的个数
- 如果返回值与count的值不一样,就会报错
- 如果大小或计数为零,则该函数返回零,
实际运用:
这里要注意:
- 如果是要写二进制文件,fopen的打开方式不能写r或者w,要写wb或者rb。
- fread和fwrite函数不仅能用在文本文件还可以运用在二进制文件,而其他几个只能运用在文本文件。
我们来对比几个函数:
scanf/fscanf/sscanf
printf/fprintf/sprintf
显而易见,上图蓝色部分是相同的,而红色部分不一样。
我们对比一下,发现printf函数和scanf函数加个f。多的那个变量为文件指针。例如:fprintf函数就是将变量从内存按照一定的格式输出到数据(文件)中。fscanf也是同样的道理。
而我们可以将变量以一定格式转换输入输出到数据,那我们是否可以将这些格式化的数据变回原来的格式呢?
答案是可以的,就是运用上图下面两个函数(sprintf函数和sscanf函数)。
如何运用呢?如下:
我们在一些网站或者平台(前端)注册的时候,要填写一些数据,这些数据就是字符串,我们就可以运用sscanf函数和sprintf函数来运用。
文件的随机读写:
fseek函数:
参数:
- 第一个参数为文件指针
- 第二个为偏移量
- 第三个为偏移量的起始位置
SEEK_SET为文件起始位置
SEEK_CUR为文件某个指定位置
SEEK_END为文件结尾位置
实际运用:
ftell函数:
ftell函数是返回文件指针相对于起始位置的偏移量。
参数:stream为文件指针。
返回值为:为long int型
实际运用:
rewind函数:
让文件指针的位置回到文件的起始位置
实际运用:
/* rewind example */ #include <stdio.h> int main () { int n; FILE * pFile; char buffer [27]; pFile = fopen ("myfile.txt","w+"); for ( n='A' ; n<='Z' ; n++) fputc ( n, pFile); rewind (pFile); fread (buffer,1,26,pFile); fclose (pFile); buffer[26]='\0'; puts (buffer); return 0; }
文本文件和二进制文件:
根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
文件读取结束的判定:
feof函数:
应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束
而不是文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束
文件缓冲区:
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。