1.文件读取结束的判定
错误案例:
牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。:
int feof( FILE *stream );
它的作用是:当文件读取结束的时候,判断是读取结束的原因是否是:遇到文件尾结束。不能根据
返回值判断文件的结束(牢记)
正确判断:
文本文件:要文件是否读取结束,要根据返回值是否是EOF(fgetc)或者NULL(fgets);
例如:
1.1 fgetc判断是否返回EOF
1.2 fgets判断是否返回NULL
二进制文件 :二进制文件读取是否结束,要根据返回值是否小于要读取的个数;
例如:
1.3 size_t fread( void *buffer, size_t size, size_t count, FILE *stream )判断返回值是否小于要读
取得个数(count);
//代码演示
文本文件:
fgetc(pf);
#include<stdio.h>
int main() {
FILE* pf = fopen("test.txt","r");
char c;
if (pf == NULL) {
perror("fopen");
return 1;
}
//读取一个字符,打印一个字符
while ((c = fgetc(pf)) != EOF) {//判断是否遇到文件尾
putchar(c);
}
printf("\n");
//判断读取结束的原因
if (ferror(pf)) {//读取过程中出错,返回非零,否则返回零
printf("IO error when reading");
}
else if (feof(pf)) {
printf("End of file reached sucessfully");
}
return 0;
}
//运行结果
fgets(pf)
#include<stdio.h>
int main() {
FILE* pf = fopen("test.txt", "r");
char str[5] = {0};
if (pf == NULL) {
perror("fopen");
return 1;
}
//读取一个字符,打印一个字符
while (( fgets(str,5,pf)) != NULL) {//判断是否遇到文件尾
puts(str);
}
printf("\n");
//判断读取结束的原因
if (ferror(pf)) {//读取过程中出错,返回非零,否则返回零
printf("IO error when reading");
}
else if (feof(pf)) {
printf("End of file reached sucessfully");
}
return 0;
}
//执行结果
二进制文件:
#include<stdio.h>
int main() {
//写入
int a[5] = { 1,2,3,4,5 };
FILE* pf=fopen("test.bin","wb");//必须二进制方式
if (pf == NULL) {
perror("fopen");
return 1;
}
fwrite(a,4,5,pf);//以二进制形式将数组写入
fclose(pf);//记得关闭
//以二进制形式读取文件
int arr[5];
pf=fopen("test.bin","rb");
if (pf == NULL) {
perror("fopen");
return 2;
}
size_t count=fread(arr,sizeof(*arr),5,pf);
if (count == 5) {
printf("Array read sucessfully.\n");
for (int i = 0; i < 5; i++) {
printf("%d ",arr[i]);
}
printf("\n");
}
else {
if (feof(pf)) {//惯用的判断,是否到文件末尾或者读取错误
printf("EOF reached scussfully.");
}
else if (ferror(pf)) {
printf("IO error when reading.\n");
}
}
fclose(pf);
pf = NULL;
return 0;
}
///执行结果
2.文件缓冲区
ANSIC 标准采用“缓冲文件系统”处理的数据⽂件的,所谓缓冲文件系统是指系统自动地在内存中为 程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓 冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
#include<stdio.h>
#include<windows.h>
int main() {
FILE* pf = fopen("test.txt","w");
if (pf == NULL) {
perror("fpoen");
return 1;
}
Sleep(1000);
char arr[] = "abcd";
fputs(arr,pf);
printf("已载入缓冲区。");
Sleep(10000);
fflush(pf);//fflush是将缓冲区的加载进文件
//关闭文件指针也能将缓冲区,全部加载进文件
pf = NULL;
return 0;
}
//此代码会先创建一个文件,等待一秒后会将字符串加载进缓冲区,此后在十秒的睡眠时间中,你可以看到创建的文件的大小是0kb,fflush后会将缓冲区的字符串全部加载进文件,你可以观察到文件大小变成1kb。
结论:
因为有缓冲区的存在,C语在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。 如果不做,可能导致读写文件的问题