判断文件结束有两种方法:EOF和feof()
查看stdio.h可以看到如下定义:
#define EOF (-1)
#define _IOEOF 0x0010
#define feof(_stream) ((_stream)->_flag & _IOEOF)
由此可以看出,这两种方式的原理是不同的。
有人说EOF只能用于文本文件,其实不然,还要看定义的变量的类型。下面这段程序对文本文件和二进制文件都可以:
int c;
while((c=fgetc(fp)) != EOF)
{
printf("%X/n", c);
}
如果读到了FF,由于c定义为int型,所以实际上c=0x000000FF,不等于EOF(-1=0xFFFFFFFF),因此不会误判为文件结尾。 但是如果把c定义为char类型,就有可能产生混淆了。
char c;
while((c=fgetc(fp)) != EOF)
{
printf("%X/n", c);
}
因为文本文件中存储的是ASCII码,而ASCII码中FF代表空值(blank),一般不使用,所以如果读文件返回了FF,说明已经到了文本文件的结尾。但是如果是二进制文件,其中可能会包含FF,因此不能把读到EOF作为文件结束的条件,此时只能用feof()函数。
在VC里,只有当文件位置指针(fp->_ptr)到了文件末尾,然后再发生读/写操作时,标志位(fp->_flag)才会被置为含有_IOEOF。然后再调用feof(),才会得到文件结束的信息。因此,如果运行如下程序:
char c;
while(!feof(fp))
{
c = fgetc(fp);
printf("%X/n", c);
}
会发现多输出了一个FF,原因就是在读完最后一个字符后,fp->flag仍然没有被置为_IOEOF,因而feof()仍然没有探测到文件结尾。直到再次调用fgetc()执行读操作,feof()才能探测到文件结尾。这样就多输出了一个-1(即FF)。
正确的写法应该是:
char c;
c = fgetc(fp);
while(!feof(fp))
{
printf("%X/n", c);
c = fgetc(fp);
} 注意这是正确的解法,谭浩强的书里有一个错误就是因为没有注意到这个问题,下面请看
这个文件复制程序代码,红色表示错误
错解:注意红色部分#include<stdio.h>
#include<stdlib.h>
main()
{
FILE *in,*out;
if((in=fopen("in.txt","r"))==NULL)
{
printf("cannot open file ");
exit(0);
}
if((out=fopen("out.txt","w"))==NULL)
{
printf("cannot open file ");
exit(0);
}
while(!feof(in))
{
fputc(fgetc(in),out);
}
fclose(in);
fclose(out);
}
看正确的代码:
#include<stdio.h>
#include<stdlib.h>
main()
{
FILE *in,*out;
char ch;
if((in=fopen("in.txt","r"))==NULL)
{
printf("cannot open file ");
exit(0);
}
if((out=fopen("out.txt","w"))==NULL)
{
printf("cannot open file ");
exit(0);
}
ch=fgetc(in);
while(!feof(in))
{
fputc(ch,out);
ch=fgetc(in);
}
/*while((ch=fgetc(in))!=EOF)
fputc(ch,out);这个代码也是正确的ch字符变量时只能应用于文本文件,*/
fclose(in);
fclose(out);
}
这么说其实feof()是可以用EOF来代替的喽?不是,这里还有一个问题。fgetc返回-1时,有两种情况:读到文件结尾或是读取错误。因此我们无法确信文件已经结束, 因为可能是读取错误! 这时我们需要feof()。
分享到:
相关推荐
判断文件结束有两种方法:EOF和feof() 查看stdio.h可以看到如下定义: #define EOF (-1) #define _IOEOF 0x0010 #define feof(_stream) ((_stream)->_flag & _IOEOF) 由此可以看出,这两种方式的原理是不同的。...
c库函数 getchar的使用细节, 以及EOF 和feof的区别
在处理大数据或者分批读取文件内容的场景下,了解如何高效、安全地利用EOF标识尤为重要。通过研究“eof.asv”中的示例,你可以学习到如何优雅地结束文件读取过程,避免无休止的循环或者错误的文件读取操作。 总结...
这意味着,如果你只是简单地调用`feof(fp)`而没有先执行读取操作,它可能不会立即反映文件的真实状态。因此,在使用`feof(fp)`时,通常会结合其他文件读取函数一起使用。 此外,`feof`函数的返回值并不区分文件结束...
了解EOF的概念对于任何涉及文件操作的开发者来说都至关重要,因为正确处理EOF能避免读取无效数据,防止程序出现未定义行为。通过调试“eof.f”文件中的子程序,我们可以更深入地理解EOF的使用方法及其在特定上下文中...
综上所述,“feof函数多读一次问题解决方案”不仅包括了对`feof()`函数特性的理解与规避策略,还涵盖了利用`fseek()`和`ftell()`等函数对文件指针进行精确控制的技巧,为高效、准确地处理文件读取提供了全面的指导。...
当你尝试从一个打开的文件流中读取数据,直至到达文件末尾,往往会利用`feof`函数来判断是否已经读到文件的结尾。如果最后一次读取操作已经到达文件末尾,那么`feof`会返回一个非零值(通常为1),否则返回0。要注意...
标题和描述中提到的知识点有C语言中的文件处理、文件结束标志EOF、FEOF函数以及文档编码的处理。在C语言中,文件的输入输出是程序设计中一个较为复杂的部分,涉及到数据流的概念以及文件指针的使用。文件结束标志EOF...
这个"eof源码.zip"文件可能会展示这些方法的具体实现,通过解压并查看源代码,你可以更深入地理解如何在实际项目中处理文件的结尾。学习和理解EOF的处理对于任何涉及文件操作的开发者来说都是至关重要的。
feof(fp))`循环用于检查`fgetc(fp)`是否返回了EOF,以此作为循环结束的条件。 需要注意的是,一些C语言标准库的实现中,在到达文件末尾后,即使再调用读取函数也不会立即返回EOF,而可能返回一个临时的字符,然后下...
当你试图从文件中读取数据但已到达文件末尾时,`fgetc()`函数会返回EOF。然而,问题在于二进制文件中可能存在数据值为-1的字节,这可能导致程序误判。 2. 示例1的问题 在示例1中,代码使用以下循环来读取二进制文件...
本文实例讲述了PHP中的feof()函数的用法,针对feof()函数...<EOF> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试PHP中的feof()函数效果
在PHP编程中,`feof()`函数是一个至关...确保在使用`feof()`时进行适当的错误检查和资源验证,可以提高代码的健壮性和可靠性。同时,熟悉其他文件操作函数和类,如`SplFileObject`,可以帮助编写更加灵活和高效的代码。
第1章 声明和初始化 基本类型 1.1 我该如何决定使用哪种整数类型? 1.2 为什么不精确定义标准类型的大小? 1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的...
本文将深入探讨如何使用C语言中的几个关键函数——`fopen`, `fclose`, `fputc`, `fgetc` 和 `feof` 来实现文件的创建、写入、读取和管理。 ### 文件操作基础 1. **文件打开(`fopen`)**: `fopen` 函数用于打开一个...
内容简介 《你必须知道的495个C语言问题》以问答...5.17 说真的,真有机器用非零空指针吗,或者不同类型用不同的表示? 61 地址0 上到底有什么? 61 5.18 运行时的整数值0转换为指针以后一定是空指针吗? 61 5.19...
在处理大文件时,为了防止内存溢出,通常推荐使用逐行读取的方式,例如结合 `fgets()` 和 `feof()`。此外,`SplFileObject` 类也是处理大文件的好选择,它提供了更高效和灵活的接口。 总之,`feof()` 是PHP中不可或...
o 6.14 说真的, 真有机器用非零空指针吗, 或者不同类型用不同的表达? o 6.15 运行时的 ``空指针赋值" 错误是什么意思? * 7. 数组和指针 o 7.1 我在一个源文件中定义了 char a[6], 在另一个中声明了 extern ...
EOF && c != ’nn’) 的代码⋯⋯ . . . . . . . . . . . . . . . . . . 14 3.7 我怎样才能理解复杂表达式?“序列点” 是什么? . . . . . . . . . 15 3.8 那么, 对于a[i] = i++; 我们不知道a[] 的哪一个分量会被...