文件结束判定与feof函数

目录

文件结束判定:
                   方法1 :fget()函数返回EOF
                   方法2 :fgets()返回NULL
                   方法3 : 利用文件长度
                   方法4 : 二进制文件利用fread()返回值
                   feof函数
                   方法5:利用feof函数判断


EOF(End of file)是C/C++里面的宏定义,具体定义式是#define EOF -1
EOF是文件结束标志
但是, EOF并不是真实存在于文件末尾的一个数据, 若读取到文件末尾的时候, 即没有数据可供读取的时候, 读文件函数fgetc就会返回EOF值。(fgets函数会返回NULL)

所以判断文件是否到末尾可以利用函数的返回值, 例如:


方法1 :fget()函数返回EOF

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;int count = 0;if ((fp = fopen("test2.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}while (fgetc(fp)!=EOF) {count++;}printf("%d\n", count);system("pause");return 0;
}

可以看到test2.txt有10个字符, 循环次数也是10
 

这种方法可以判定文件是否结束, 但需要不停地循环调用函数, 在执行效率较低


方法2 :fgets()返回NULL

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;int i;char str1[4];char str2[4];char str3[4];char str4[4];char* str[4] = { str1,str2,str3,str4 };if ((fp = fopen("test2.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}for (i = 0; fgets(str[i], 4, fp) != NULL; ++i) { printf("str%d : %s\n", i + 1, str[i]);}printf("i = %d\n", i);system("pause");return 0;
}

可以看到10个字符,fgets函数一次读三个字符, 读了四次完成, 读到文件末尾返回NULL

       


方法3 : 利用文件长度

利用fseek(), ftell()函数计算出文件长度(大小)
链接: fseek()和ftell()函数

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;int n;char str[12] = { 0 };if ((fp = fopen("test2.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}//fseek(fp, 0, 2);//fp到文件末尾n = ftell(fp);//fp到文件开头的偏移量, 这里就是文件长度rewind(fp);//fp重新指向文件开头//for (int i = 0; ftell(fp) != n; ++i) {str[i] = fgetc(fp);}printf("str : %s\n", str);system("pause");return 0;
}

       


方法4 : 二进制文件利用fread()返回值

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define SIZE 5
int main() {FILE* fp;double arr[SIZE] = { 1.1,2.2,3.3,4.4,5.5 };double num;if ((fp = fopen("test3.txt", "wb")) == NULL) {printf("error\n");system("pause");return 0;}fwrite(arr, sizeof(arr[0]), SIZE, fp);fclose(fp);fp = NULL;if ((fp = fopen("test3.txt", "rb")) == NULL) {printf("error\n");system("pause");return 0;}while (fread(&num, sizeof(arr[0]), 1, fp)) {printf("%.1f\n", num);}fclose(fp);system("pause");return 0;
}

fread()函数会返回读取成功的个数, fread(&num, sizeof(arr[0]), 1, fp)中每次读取1个字节长为sizeof(arr[0])的数据, 若成功则返回返回成功的个数1, 若失败也就是成功0个, 返回0

    


feof函数

定义于头文件 <stdio.h>  
int feof( FILE *stream ) 
检查是否已抵达给定文件流的结尾
当文件读取结束时, 若是遇到文件尾结束,则返回

注意 : 在文件读取过程中,不能用feof函数的返回值直接用来判断是否遇到末尾结束。但可以用于当文件读取结束的时候,判断是读取失败结束(返回0值),还是遇到文件尾结束(返回非0值)。
即, 文件读取结束后, feof才能判断, 所以我们不能在进行读取文件时, 直接用feof()当做条件来判断, 
我们来看下面几个例子 :

1. feof的经典错误

  文件test1.txt为空

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;if ((fp = fopen("test1.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}if (feof(fp)) {printf("test1.txt为空\n");}else {printf("test1.txt不为空\n");}system("pause");return 0;
}

feof函数如果可以之间判断是否到文件尾, 应该会输出test1.txt为空, 结果却不是, 结果如图:

但如果我们在用feof()函数之前加上一个语句fgetc(fp)就会出现正确结果

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;if ((fp = fopen("test1.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}fgetc(fp);if (feof(fp)) {printf("test1.txt为空\n");}else {printf("test1.txt不为空\n");}system("pause");return 0;
}

结果如图 :

我们再来看,test2.txt 如图 :

我们来看这段代码,

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;int count = 0;if ((fp = fopen("test2.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}while (!feof(fp)) {fgetc(fp);printf("%d\t", ++count);}system("pause");return 0;
}

test2中共有10个字符, 结果应该输出  1 2 3 4 5 6 7 8 9 10, 循环十次. 实则不然, 循环了11次, 如图:

我们再来看

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;int n;if ((fp = fopen("test2.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}while (! (n = feof(fp))) {printf("feof(fp)=%d, ", n);printf("%d\n", fgetc(fp));}printf("feof(fp)=%d", n);system("pause");return 0;
}

运行结果如图, 输出feof的返回值和字符的ASCII码, 当fgetc读到文件末尾时返回EOF(-1), 此时 feof返回值为-1(非0)

通过这几段代码我们发现 , feof()是在别的函数读取到文件末尾后继续读取失败后才做出的文件读取结束的判断

我们可以这样来解决这个问题, 如以下代码:


方法5:利用feof函数判断

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main() {FILE* fp;char c;if ((fp = fopen("test2.txt", "r")) == NULL) {printf("error\n");system("pause");return 0;}c = fgetc(fp);while (! feof(fp)) {printf("%c %d\n", c, c);c = fgetc(fp);}system("pause");return 0;
}

运行结果如图 , 实际是c读取了-1的值但并未输出 .

目前就理解到这, 感觉并不是大彻大悟, 以后有新的理解再补充吧

文件结束判定与feof函数相关推荐

  1. 文件的结束判定与feof函数

    目录 文件结束判定 1.fgetc()函数返回EOF 2.fgets()函数返回NULL 文件结束判定 1.fgetc()函数返回EOF EOF(End of file)是C/C++里面的宏定义,具体 ...

  2. 文件结束的判定与feof函数

    文件结束的判断: 1.fget()读取结束后返回EOF. #include<stdio.h> #include<stdlib.h> int main() {FILE* fp = ...

  3. C语言:feof函数的坑

    目录 引言 feof()函数 引言 做课设的时候踩到这个坑,跟大家分享一下 feof()函数 看一下下面的代码 #include<stdio.h> int main() {FILE *fp ...

  4. 关于使用fgetc函数和feof函数的一些注意事项

    关于使用fgetc函数和feof函数的一些注意事项 众所周知,文件分为二进制文件和文本文件,它们在磁盘中的存储方式是相同的,都是二进制存储,但是它们的读取方式不同.对于文本文件,我们通常使用逐个字节读 ...

  5. Linux c/c++编程--feof函数

    函数原型:  int feof ( FILE * stream ); 头文件: #include <stdio.h> 参数: stream FILE结构的指针.指向一个文件流对象的指针.例 ...

  6. c语言中关于文件读取结束的判定,以及feof函数的理解

    判断一个文件的读取是否结束,很多人,会想到用feof函数来判定,的确需要用到这个函数,但是仅仅靠这个函数是不够的. 错误用法: #include<stdio.h>int main() {F ...

  7. C语言文件操作(四) —— 文件读取结束的判定(feof、ferror)

            目录 1.feof.ferror 函数返回值 (1) feof 函数 (2) ferror 函数 2.feof.ferror 函数函数使用 fgetc.fgets的返回值说明都有提到一 ...

  8. PHP feof() 函数读文件的使用

    (PHP 4, PHP 5) feof - 测试文件指针是否到了文件结束的位置 如果服务器没有关闭由 fsockopen() 所打开的连接,feof() 会一直等待直到超时而返回TRUE.默认的超时限 ...

  9. Linux C编程--操作文件结束和错误的判断方法(函数)

    多数函数(fgets().gets().putc().ungetc().fread()等)当调用不成功时都返回EOF,EOF的值为0,它既用于报告文件结束,也用于报告错误情形下的返回.因此,为了区分究 ...

最新文章

  1. List常用方法总结 遍历集合的方法
  2. 普通页面使用vue.js心得
  3. C# winform中一个类中如何调用另一个窗体的控件或方法
  4. 编译Ruby2.0 问题解决
  5. android Sqlite小记
  6. ajax传值controller怎么写,ajax如何传递参数给controller
  7. 图片旋转 rotate
  8. 数据结构(十)二叉排序树
  9. 新装WIN7 UPDATE 无法更新
  10. 点击率预估与冷启动(一)
  11. 3ds Max Graphic Device Error 怎么解决(设置问题)
  12. wkhtmltopdf 照片不显示的问题
  13. 样本方差为什么要除n-1,而不是n
  14. 服务器gpt分区不能安装系统,安装Win10原版系统提示“Windows无法安装到GPT分区形式磁盘”怎么办...
  15. sql语句中的子查询
  16. 基于arduino的5路循迹小车(1)
  17. iOS 13 DarkMode 暗黑模式
  18. 不只食品溯源,区块链技术被运用在冬奥会的各个环节
  19. 常见的U盘数据丢失问题及U盘数据恢复教程?
  20. 帝国、PHPCMS及织梦三款CMS比较

热门文章

  1. Java面试题:猫吃老鼠问题
  2. Apache NiFi用户指南
  3. 九阴服务器维护,《九阴真经》-官方网站-一亿人的真武侠梦,开创全自由空中打斗...
  4. (最简单)小米手机5X的usb调试模式在哪里开启的流程
  5. React Hooks 的原理
  6. 完美3D建模入门基础知识点总结,看完你的游戏建模就完全入门了!
  7. java wifi模块源码_Wifi模块
  8. uni-app与Html 标签的区别
  9. 高考选地理化学生物能考计算机专业吗,高考“3+3”中,选择了化学、生物、地理,那么将来能上什么专业?...
  10. IIS健全应用程序池设置 @阿良.NET(转载)