C/C++中读取文件判断是否读取结束

来源:互联网 发布:java编程思想4 pdf 编辑:程序博客网 时间:2024/06/11 08:19

最近用C++读取文件时遇到了一个问题,读取如下图所示的文件时,使用C中的feof()判断是否读取结束,总会在文件末尾处总会多读一遍。


可以看到我读取的文件格式是比较简单的,没两行为一对,第一行有两个int类型的数字,第二行是一个字符串,包含图像的名称。

先上我读取文件的代码:

void read(string name){FILE *file = fopen(name.c_str(), "r");while (!feof(file)){int i, j;fscanf(file, "%d%d\n", &i, &j);char filename[100];fgets(filename, 100, file);filename[strlen(filename) - 1] = '\0';}}
可以看到,读取的代码非常简单,但是这样会出现一个问题,最后一行会重复输出一遍。

造成这个问题的原因在于feof在真正文件读取结束后还会继续在判断一遍才会结束。

为了解决这个问题,有人是使用了如下方法

char c;c = fgetc(fp);while(!feof(fp)){printf("%X/n", c); c = fgetc(fp);} 
这种方法确实可以避免重复读取最后一行的问题,但是这种方法更加适合于每次读取单个字符的情况,对于我遇到的这种,需要读取int和字符串的情况就不是很适用,最终我在网上找到了一种万无一失的方法解决feof的问题,那就是不用它。。。

我们适用fseek和ftell来配合判断是否读取到文件末尾。

void read(string name){FILE *file = fopen(name.c_str(), "r");fseek(file, 0L, SEEK_END);long end = ftell(file);fseek(file, 0L, SEEK_SET);long start = ftell(file);while (end != start){int i, j;fscanf(file, "%d%d\n", &i, &j);char filename[100];fgets(filename, 100, file);filename[strlen(filename) - 1] = '\0';cout << filename << endl;start = ftell(file);}}
大体思路就是首先通过fseek得到文件末尾的位置,然后在读取文件以后不断计算当前读取的文件位置,如果读取后发现当前位置与文件末尾位置相同,则停止继续读取文件。

这种方法的好处是万金油,记住这一种,以后遇到所有需要读取全部文件的情况都可以适用。简单易懂。

当然利用C++的方法也可以实现这一需求,但是有些情况下C++的读写速度明显低于C语言,而且C++兼容C语言。



0 0
原创粉丝点击