结论:EOF是在头文件stdio.h中预定义的一个宏,而eof(end of file)是一个与标准输入/输出流相关联的标志位。当文件指针已经指向文件尾且再次尝试读取时,eof标志会被设置。同时,某些函数会在读取到文件尾(即eof标志被设置)时返回EOF作为标识。

    另注:

  笔者经常会在C进行文件I/O操作时出现文件读取实际尚未结束(未读取至文件末尾),但系统显示已读取至文件尾的情况。具体原因如下。

  在过去的操作系统中,文件以文件存储占用的扇区数作为文件大小的计数单位,故而如果文件的大小不能恰好填满存储文件的最后一个扇区,则需要对该扇区剩余的空间进行填充,过去填充使用的是值为26(0x1a)的字节,也就是某些系统中 Ctrl+Z 的对应码值,故而在读取文件过程中,读取到值26,则系统认为文件已经到达末尾,不再读取。在 windows 环境下,终端输入可以使用 Ctrl + z 作为输入的 EOF 标志,而 linux 环境下,则可使用 Ctrl + d 作为输入的结束标志。

  现在的操作系统开始使用字节作为文件大小的计数单位,但古老的习惯还是被保留下来。为了避免文件读取过程中存在值为26的数据使得系统误认为文件结束而停止读取,可以将文件以二进制文件格式打开。

  

  EOF

  EOF常被在程序中用于判断(文件)缓冲区是否结束,实际在头文件 stdio.h 中定义。

  

  可以看到EOF是一个头文件中预定义的宏,其值为  -1 。也就是说,在程序中使用的EOF实际为一个预定义的常数。而许多的函数会在读取至文件末尾或出现错误时,会返回EOF,作为处理状态的一种描述,如下文的getchar.

  

  getchar(getchar C++ Reference)

  函数声明:int getchar(void);

  函数功能:当函数读取成功时,会返回成功读取的字符数据(转化为 int 类型),若失败,则返回值为EOF,也就是上文说的值为 -1 的宏定义。

  

  可以从上面的介绍中看到,函数除返回EOF外,还会设置标准输入( stdin )的 eof 标志/error标志,可供feof或ferror函数使用。也就是说,EOF(宏定义)与eof标志并不是同一个东西

  getchar函数在头文件stdio.h中定义,具体实现如下:

  

  显然,读取字符数据并指向下一个待读取的数据操作是由 *stdin->_ptr++ 来实现的,而返回 EOF 以及将上文提及的error标志和eof标志则是由函数_filbuf实现。

  

  从上面资料可以得到结论:

  (1)对一般的文件/输入流,存在一个指向待读取数据位置的内部的指针(如上面的stdin->_ptr),每次读取数据完成该内部指针会移动指向下一个待读取数据;

  (2)文件/输入流还存在两个特殊的标志 eof 和 error ,它们可以分别被函数feof和ferror处理,当文件读取至文件末尾或出现错误时,相应的标志位eof/error会被设置;

  (3)一些函数在发生错误或读取至文件末尾时,会返回EOF,其为值为 -1 的宏,同时设置文件/输入流的某些标志;

  feof( feof C++ Reference)

  函数声明:int feof(FILE *stream);      //stream为对应的文件流的标志

  函数功能:会检查与文件对应流的eof( end of file )标志是否被设置,如果被设置则返回非零值,如未被设置,则返回0.

  注意:feof函数只检查eof标志是否被设置,其本身并不会设置eof标志,设置eof标志的是试图进行数据读取的操作

  示例:

 #include<stdio.h>

 int main(void)
{
FILE *ptr = fopen("a.txt","r"); if(!ptr)
{
printf("打开文件失败!\n");
return -;
} char ch;
int count = ; while(!feof(ptr)) //检测到EOF标志则停止
{
count++;
ch = fgetc(ptr);
printf("%c",ch);
}
printf("%5d",count);
printf("\n"); fclose(ptr);
return ;
}

  示例代码读取的a.txt的内容为"12".代码会逐字节显示文件的内容(19、20行),以及读取的次数(18、22行)。

  执行结果下图所示:

  

  (1)EOF标志未被设置时,feof函数会返回0,eof标志被设置后,feof返回非零值;

  (2)每次读取成功后,指向文件流内部的指针会顺序移动读取的字数个字节(对文本来说),这样使得内部指针总是指向待读取的下一个字符;

  (3)执行流程 : feof返回值为0,第一次循环,ch = ‘1’,count = 1,流内部的位置指针指向‘2’;feof返回值为0,第二次循环,ch = ‘2’,count = 2,流内部的位置指针指向文件末尾,但此时EOF并未被设置;feof返回值仍为0,第三次循环,会试图访问文件的末尾,count = 3,eof 标志被设置,下一次的feof返回值为非0值,故而结束循环;(笔者在CodeBlocks12.13中调试时,第三次循环时ch的值为-1,即为EOF,printf并没有将其显示至控制台)

  文件流内部存在标志读取位置的内部指针,该位置指针指向文件尾并不会设置对应文件流的eof 标志,只有当该位置指针指向文件尾,并再次试图进行顺序读操作时,才会设置eof标志。

  EOF为一个定义的宏常量,而eof标志为与文件/输入流相关的一个标志,当位置指针已指向文件末尾并再次试图读取输入时,会设置eof标志,同时为了表明发生的情况,函数一般会返回EOF用来表示文件读取至末尾或发生错误。

 

EOF及相关函数的更多相关文章

  1. fopen()及相关函数使用

    函数简介 函数功能:打开一个文件 函数原型:FILE * fopen(const char * path,const char * mode); ],_wfopen 所需库:<stdio.h&g ...

  2. 学习PHP中的iconv扩展相关函数

    想必 iconv 这个扩展的相关函数大家多少都接触过,做为 PHP 的默认扩展它已经存在了很久,也是我们在操作字符编码时经常会使用的函数.不过除了 iconv() 这个函数外,你还知道它的其它函数吗? ...

  3. linux下EOF写法梳理

    在平时的运维工作中,我们经常会碰到这样一个场景:执行脚本的时候,需要往一个文件里自动输入N行内容.如果是少数的几行内容,还可以用echo追加方式,但如果是很多行,那么单纯用echo追加的方式就显得愚蠢 ...

  4. php定界符<<<EOF讲解(转)

    Heredoc技术.可用来输出大段的html和javascript脚本 1.PHP定界符的作用就是按照原样,包括换行格式什么的,输出在其内部的东西: 2.在PHP定界符中的任何特殊字符都不需要转义:  ...

  5. while(cin.eof)出错 poj

    zoj遇到c++如何判定输入流结尾的问题,一不小心就超时了 楼下的代码可以通过zoj #include<iostream> using namespace std; int main(){ ...

  6. c++ eof()函数

    C++ eof()函数可以帮助我们用来判断文件是否为空,抑或是判断其是否读到文件结尾.在这里我们将会对其进行详细的介绍. C++编程语言中的很多功能在我们的实际应用中起着非常大的作用.比如在对文件文本 ...

  7. 【转】 解读EOF

    解读EOF 标签: fplinuxc语言filestream 2012-01-31 22:05 439人阅读 评论(0) 收藏 举报  分类: C.C++_程序设计(20)  我学习C语言的时候,遇到 ...

  8. Linux C 字符函数 getchar()、putchar() 与 EOF 详解

    首先给出<The_C_Programming_Language>这本书中的例子: #include <stdio.h> int main() { int c; c = getc ...

  9. Ext3文件系统mount选项和文件属性介绍

    mount选项 设置方式 ext3 mount选项可以通过多个方式进行设置:1)内核编译时: 内核menuconfig通过CONFIG_EXT3_DEFAULTS_TO_ORDERED编译控制选项,来 ...

随机推荐

  1. 在ubuntu下使用Eclipse搭建Hadoop开发环境

    一.安装准备1.JDK版本:jdk1.7.0(jdk-7-linux-i586.tar.gz)2.hadoop版本:hadoop-1.1.1(hadoop-1.1.1.tar.gz)3.eclipse ...

  2. C#控件随窗体大小改变而改变

    几种方法:1.点击控件,属性,里面有一个Dock,选择Fill,就会变得和它的父容器一样大.而且会随之变化.2.点击控件,属性,里面有一个Anchor,选择Top,Right,Bottom,Left. ...

  3. 入门系列之在Ubuntu上使用Netdata设置实时性能监控

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由小翼 发表于云+社区专栏 介绍 Netdata通过可扩展的Web仪表板提供准确的性能监控,可以显示Linux系统上的流程和服务.它监控 ...

  4. Xshell关闭导致jar服务终止,使Jar在CentOS后台运行

    环境:Xsehll6,CentOS7 在项目文件夹新建一个runjar.sh 在sh中写入(举例说明) nohup java -Dfile.encoding=UTF- -jar fin-mgmt-.j ...

  5. resteasy上传单个文件/多个文件到阿里云服务器

    代码如下: ExcelServerController.java package com.xgt.controller; import com.xgt.bean.bs.ExcelBean; impor ...

  6. 006.ASP.NET MVC ActionResults说明

    原文:http://rachelappel.com/asp.net-mvc-actiohttp://i.cnblogs.com/EditPosts.aspx?postid=3857238&up ...

  7. Oracle数据库查看已添加的索引和创建索引

    /** *查看目标表中已添加的索引 * */ --在数据库中查找表名 select * from user_tables where table_name like 'tablename%'; --查 ...

  8. JAVA学习之路(多线程)---模拟售票(细解)

    首先看题目描述: 假设有火车票100张,创建4个线程模拟4个售票点,每100ms售出一张,打印出售票过程,格式如下: 窗口3:卖出第100张票 窗口4:卖出第99张票 ............ ... ...

  9. 六、Spring之DI的Bean的作用域

    Spring提供“singleton”和“prototype”两种基本作用域,另外提供“request”.“session”.“global session”三种web作用域:Spring还允许用户定 ...

  10. 用css3+js写了一个钟表

    有一天看到css3旋转这个属性,突发奇想的写了一个钟表(没做浏览器兼容),来一起看看是怎么写的吧! 先给个成品图,最终结果是个样子的(动态的). 首先,思考了一下页面的布局,大致需要4层div,最底层 ...