EOF详解

EOF是end of file的缩写,表示"文字流"(stream)的结尾。这里的"文字流",可以是文件(file),也可以是标准输入(stdin)。

EOF不是特殊字符,而是一个定义在头文件stdio.h的常量,一般等于-1。

#define EOF (-1)

在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志

//文件结尾 示例
#include<stdio.h>
void main()
{FILE *fp;char c;fp=fopen("abc.txt","r");while((c=fgetc(fp))!=EOF)printf("%c",c);fclose(fp);
}

除了表示文件结尾,EOF还可以表示标准输入的结尾。但是,标准输入与文件不一样,无法事先知道输入的长度,必须手动输入一个字符,表示到达EOF。

1)getchar()的返回值与EOF进行比较。如果不相同,则你还没有到达文件结尾。换句话说,你可以使用如下表达式:

while ((ch = getchar ()) != EOF)

Unix系统中,你能通过在一行开始键入Ctrl+D来从键盘模拟文件结束条件;DOS系统则使用Ctrl+Z来达到这个目的。

顺便提一句,Linux中按下Ctrl+Z,表示将该进程中断,在后台挂起,用fg 命令可以重新切回到前台;按下Ctrl+C表示终止该进程。

如果真的想输入Ctrl+D,则必须先按下Ctrl+V,然后就可以输入Ctrl+D,系统就不会认为这是EOF信号。Ctrl+V表示按"字面含义"解读下一个输入,要是想按"字面含义"输入Ctrl+V,连续输入两次就行了。

#include <stdio.h>
int main(void)
{  char ch;  while ((ch = getchar ()) != EOF)  putchar (ch);  return 0;
}  
2)scanf()函数 返回一个整数值,这个值是成功读取的项目数,或者当遇到文件结束时返回一个EOF(文件结尾符)。
#include <stdio.h>
int main (void)
{int n = 0;while (scanf ("%d", &n) != EOF){printf ("hello world!\n");}return 0;
}
3)fclose ( )函数 如果成功返回 0,否则返回EOF(-1)。
4)如果读入字符时发现已经到达文件结尾,getc ( )函数 会返回一个特殊值EOF。
int ch;
FILE * fp;
fp = fopen ("abc.txt", "r");
while ((ch = getc (fp)) != EOF)
{putchar (ch);
}
feof ( )函数:
函数原型:

int feof(FILE * stream);
所在头文件:
stdio.h
返回值:
返回非零值代表已到达文件尾
函数说明:
feof ( ) 用来侦测是否读取到了文件尾, 尾数stream 为fopen()所返回之文件指针. 如果已到文件尾则返回非零值, 其他情况返回0
//示例
#include <stdio.h>
int main ()
{FILE *fp;int c;fp = fopen("abc.txt","r");if(fp == NULL) {perror("打开文件时发生错误");return(-1);}while(1){c = fgetc(fp);if( feof(fp) ) //到文件结尾 feof (fp) 为 1{ break ;}printf("%c", c);}fclose(fp);return(0);
}

EOF与feof函数区别

EOF是文本文件结束的标志。在文本文件中,数据是以字符的ASCⅡ代码值的形式存放,普通字符的ASCⅡ代码的范围是32到127(十进制),EOF的16进制代码为0xFF(十进制为-1),因此可以用EOF作为文件结束标志。 当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。
为解决这一个问题,ASCI C提供一个feof函数,用来判断文件是否结束。feof函数既可用以判断二进制文件又可用以判断文本文件。
注意:feof ( )函数,读取文件的最后一个字符以后,C 语言的feof ( ) 函数依然返回 0,表明没有到达文件结尾;只有当fgetc ( ) 向后再读取一个字符(即越过最后一个字符),feof()才会返回一个非零值,表示到达文件结尾。
//示例
#include <stdio.h>
int main ()
{  FILE *fp;  int c;  fp = fopen("abc.txt","r");  if(fp == NULL)   {  perror("打开文件时发生错误");  return(-1);  }  c = fgetc(fp);  while(!feof (fp))  {  printf("%c", c);  c = fgetc(fp); //打印所有的数据之后,需要再fgetc(fp)一次,函数feof(fp)的返回值才为真}  fclose(fp);  return(0);
}  
//改良版
#include <stdio.h>
int main ()
{  FILE *fp;  int c;  fp = fopen("abc.txt","r");  if(fp == NULL)   {  perror("打开文件时发生错误");  return(-1);  }  while(1)  {  c = fgetc(fp);  if( feof(fp) ) //到文件结尾 feof (fp) 为 1  {   break ;  }  printf("%c", c);  }  fclose(fp);  return(0);
}  

ferror()函数
函数原型:

int ferror(FILE *stream)
返回值:
如果设置了与流关联的错误标识符,该函数返回一个非零值,否则返回一个零值。
函数描述:
ferror,函数名,在调用各种输入输出函数(如 putc.getc.fread.fwrite等)时,如果出现错误,除了函数返回值有所反映外,还可以用ferror函数检查。 它的一般调用形式为 ferror(fp);如果ferror返回值为0(假),表示未出错。如果返回一个非零值,表示出错。应该注意,对同一个文件 每一次调用输入输出函数,均产生一个新的ferror函 数值,因此,应当在调用一个输入输出函数后立即检 查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。

#include <stdio.h>
int main()
{FILE *fp;char c;fp = fopen("file.txt", "w");c = fgetc(fp);if( ferror(fp) ){printf("读取文件:file.txt 时发生错误\n");}clearerr(fp);if( ferror(fp) ){printf("读取文件:file.txt 时发生错误\n");}fclose(fp);return(0);
}
假设我们有一个文本文件 file.txt,它是一个空文件。让我们编译并运行上面的程序,因为我们试图读取一个以只写模式打开的文件,这将产生以下结果。
读取文件:file.txt 时发生错误
通过上面的例子可以看到,clearerr 清除了出错标志。

clearerr 函数

函数原型:
void clearerr(FILE *stream)
函数功能:
在大多数实现中,为每个流在 FILE 对象中维护了两个标志:
出错标志
文件结束标志
调用 clearerr 可以清除这两个标志。

C语言再学习 -- EOF、feof函数、ferror函数相关推荐

  1. C语言再学习 -- 关键字return和exit ()函数

    终于到了最后一个关键字 return 了.感觉时间过的飞快,转眼间又是一年,如果时间可以 return 就好了. 一.return 介绍 参看:C语言中return 用法 1.含义: return 表 ...

  2. C语言再学习 -- 常用头文件和函数(转)

    参看:C/C++常用头文件及函数汇总 linux常用头文件如下: POSIX标准定义的头文件 <dirent.h>        目录项 <fcntl.h>         文 ...

  3. C语言semaphore头文件,C语言再学习 -- 常用头文件和函数

    Linux常用头文件如下: POSIX标准定义的头文件 < dirent.h>        目录项 < fcntl.h>         文件控制 < fnmatch. ...

  4. C语言再学习 -- ctype.h字符判断函数

    参看:ctype.h 百度百科 ctype.h是C标准函数库中的头文件,定义了一批C语言字符分类函数(C character classification functions),用于测试字符是否属于特 ...

  5. C语言再学习 -- 输入/输出

    一.缓冲区 输入字符的立即回显是非缓冲或直接输入的一个实例,它表示你说键入的字符被收集并存储在一个被成为缓冲区的临时存储区域中.按下回车可使你所键入的字符块对程序变成可用. 为什么需要缓冲区?首先,将 ...

  6. C语言再学习 -- 文件

    文件是什么 一个文件(file)通常就是磁盘上的一段命名的存储区.C 将文件看成是连续的字节序列,其中每一个字节都可以单独地读取. 二进制和文本模式 1.在windows系统中,文本模式下,文件以&q ...

  7. UNIX再学习 -- exit 和 wait 系列函数

    我们一开始讲进程环境时,就有提到了.进程有 8 种方式使进程终止. 其中 5 种为正常终止,它们是: (1)在 main 函数中执行 return (2)调用 exit 函数,并不处理文件描述符,多进 ...

  8. C语言再学习 -- C 预处理器

    gcc/cc xxx.c  可以编译链接C源程序生成一个可执行文件 a.out 整个过程中可以划分为以下的4步流程: (1)预处理/预编译: 主要用于包含头文件的扩展,以及执行宏替换等 //加上 -E ...

  9. C语言再学习 -- 时间函数

    在软件设计中经常会用到关于时间的处理,用来计算语句.函数的执行时间,这时就需要精确到毫秒甚至是微妙的时间.我们首先来介绍一下,时间单位: 时间单位还有:秒(s).毫秒(ms).微秒 (μs).纳秒(n ...

最新文章

  1. 大小端存储模式的理解和判断
  2. JavaScript强化教程-JS面向对象编程
  3. 3. Leetcode 16. 最接近的三数之和 (数组-双向双指针)
  4. 为什么在Python中使用string.join(list)而不是list.join(string)?
  5. SCAU_WeiShenWahle 之省赛任务
  6. 无心剑中译叶芝《情愁》
  7. 地税某数据库异常重启和重启后数据库运行缓慢问题的解决过程
  8. 常用 html 标签
  9. 大学生医保的报销范围
  10. jQuery活动倒计时插件
  11. c语言网吧计费管理小项目,c语言网吧计费系统小项目.doc
  12. 《墨菲定律》读书笔记之第一章——成功学的秘密
  13. HTML_body中常用的标签部分
  14. 通过Docker 安装 cloudera manager 平台
  15. 如何新建一个看不见的文件夹(我们的游戏都在里头)
  16. sql语句查询,多字段like模糊查询优化
  17. 高德地图——骑行路线骑行指定
  18. 让最小化安装的CentOS 6.8能够浏览网页
  19. A hard puzzle(HDU1097)(快速幂取模)
  20. MATLAB闪退,无法打开

热门文章

  1. 【python编程】基础知识2—语句:循环,条件,break,pass,continue
  2. NIFI分页获取Mysql数据_导入到Hbase中_并可通过phoenix客户端查询_含金量很高的一篇_搞了好久_实际操作05---大数据之Nifi工作笔记0045
  3. Unity实现以鼠标为中心缩放物体(一)
  4. USART串口通信实验
  5. ClickHouse 实现有序漏斗分析与数据可视化
  6. excel2007剔除重复数据,计算百分比
  7. jQuery拉开关闭帷幕
  8. Color.Lerp的使用
  9. C++ 教学:从入门 到 入坟[7]
  10. python注释掉一段代码_python将一段程序无效掉的方法