我学习C语言的时候,遇到的一个问题就是EOF

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

比如,下面这段代码就表示,如果不是文件结尾,就把文件的内容复制到屏幕上。

  int c;

  while ((c = fgetc(fp)) != EOF) {

    putchar (c);

  }

很自然地,我就以为,每个文件的结尾处,有一个叫做EOF的特殊字符,读取到这个字符,操作系统就认为文件结束了。

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

  #define EOF (-1)

于是,我就困惑了。

如果EOF是一个特殊字符,那么假定每个文本文件的结尾都有一个EOF(也就是-1),还是可以做到的,因为文本对应的ASCII码都是正值,不可能有负值。但是,二进制文件怎么办呢?怎么处理文件内部包含的-1呢?

这个问题让我想了很久,后来查了资料才知道,在Linux系统之中,EOF根本不是一个字符,而是当系统读取到文件结尾,所返回的一个信号值(也就是-1)。至于系统怎么知道文件的结尾,资料上说是通过比较文件的长度。

所以,处理文件可以写成下面这样:

  int c;

  while ((c = fgetc(fp)) != EOF) {

    do something

  }

这样写有一个问题。fgetc()不仅是遇到文件结尾时返回EOF,而且当发生错误时,也会返回EOF。因此,C语言又提供了feof()函数,用来保证确实是到了文件结尾。上面的代码feof()版本的写法就是:

  int c;

  while (!feof(fp)) {

    c = fgetc(fp);

    do something;

  }

但是,这样写也有问题。fgetc()读取文件的最后一个字符以后,C语言的feof()函数依然返回0,表明没有到达文件结尾;只有当fgetc()向后再读取一个字符(即越过最后一个字符),feof()才会返回一个非零值,表示到达文件结尾。

所以,按照上面这样写法,如果一个文件含有n个字符,那么while循环的内部操作会运行n+1次。所以,最保险的写法是像下面这样:

  int c = fgetc(fp);

  while (c != EOF) {

    do something;

    c = fgetc(fp);

  }

  if (feof(fp)) {

    printf("\n End of file reached.");

  } else {

    printf("\n Something went wrong.");

  }

除了表示文件结尾,EOF还可以表示标准输入的结尾。

  int c;

  while ((c = getchar()) != EOF) {

    putchar(c);

  }

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

Linux中,在新的一行的开头,按下Ctrl-D,就代表EOF(如果在一行的中间按下Ctrl-D,则表示输出"标准输入"的缓存区,所以这时
必须按两次Ctrl-D);Windows中,Ctrl-Z表示EOF。(顺便提一句,Linux中按下Ctrl-Z,表示将该进程中断,在后台挂起,用
fg命令可以重新切回到前台;按下Ctrl-C表示终止该进程。)

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

文件流结尾的EOF详解的更多相关文章

  1. C语言对文件的操作函数用法详解2

    fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const  ...

  2. C语言对文件的操作函数用法详解1

    在ANSIC中,对文件的操作分为两种方式,即: 流式文件操作 I/O文件操作 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef str ...

  3. robots.txt文件配置和使用方法详解

    robots.txt文件,提起这个概念,可能不少站长还很陌生:什么是robots.txt文件?robots.txt文件有什么作用?如何配置robots.txt文件?如何正确使用robots.txt文件 ...

  4. DOS文件转换成UNIX文件格式详解

    转:DOS文件转换成UNIX文件格式详解 由windows平台迁移到unix系统下容易引发的问题:Linux执行脚本却提示No such file or directory dos格式文件传输到uni ...

  5. express文件上传中间件Multer详解

    express文件上传中间件Multer详解 转载自:https://www.cnblogs.com/chengdabelief/p/6580874.html   Express默认并不处理HTTP请 ...

  6. [转帖]XCopy复制文件夹命令及参数详解以及xcopy拷贝目录并排除特定文件

    XCopy复制文件夹命令及参数详解以及xcopy拷贝目录并排除特定文件 https://www.cnblogs.com/smartsmile/p/7665979.html xcopy dirA dir ...

  7. WebService核心文件【server-config.wsdd】详解及调用示例

    WebService核心文件[server-config.wsdd]详解及调用示例 作者:Vashon 一.准备工作 导入需要的jar包: 二.配置web.xml 在web工程的web.xml中添加如 ...

  8. 转:关于将Java编译过的.class文件打成jar可执行文件/JAR详解

    原文链接:关于将Java编译过的.class文件打成jar可执行文件/JAR详解 如何把 java 程序编译成 .exe 文件.通常回答只有两种,一种是制作一个可执行的 JAR 文件包,然后就可以像. ...

  9. 原来Github上的README.md文件这么有意思——Markdown语言详解(sublime text2 版本)

    一直想学习 Markdown 语言,想起以前读的一篇 赵凯强 的 博客 <原来Github上的README.md文件这么有意思——Markdown语言详解>,该篇博主 使用的是Mac系统, ...

随机推荐

  1. golang round

    func Round(f float64, n int) float64 {pow10_n := math.Pow10(n)return math.Trunc((f+0.5/pow10_n)*pow1 ...

  2. 洛谷 P2640 神秘磁石

    P2640 神秘磁石 题目背景 在遥远的阿拉德大陆,有一种神秘的磁石,是由魔皇制作出来的, 题目描述 1.若给他一个一维坐标系,那么他的磁力一定要在素数坐标的位置上才能发挥的最大(不管位置坐标的大小, ...

  3. 程序猿必须知道FTP命令

                                             程序猿必须知道FTP命令 文件传输软件的使用格式为:FTP<FTP地址>.若连 接成功.系统将提示用户输入 ...

  4. Scala入门到精通——第二十二节 高级类型 (一)

    作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 this.type使用 类型投影 结构类型 复合类型 1. this.type使用 c ...

  5. Mybatis like查询的写法--转载

    原文地址:http://lavasoft.blog.51cto.com/62575/1386870 Mybatis like查询官方文档没有明确的例子可循,网上搜索了很多,都不正确. Mybatis ...

  6. js常用数据转换&判断

    数组转字符串 var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); //"0-1-2-3-4" 字符串转数组 ...

  7. Ubuntu 14.04安装teamviewer 远程桌面

    teamviewer 真是一款非常强大的远程登录软件,可以跨Windows和Ubuntu远程登录,但是在64bit的Ubuntu下安装时,按照官方安装方法总是会遇到问题,下面说一下如何安装: 安装i3 ...

  8. iOS_07_流程控制

    一.流程控制 * 顺序结构:默认的流程结构.按照书顺序执行每一条语句. * 选择结构:对给定得条件进行判断,再根据判断结果来决定执行哪一段代码. * 循环结构:在给定条件成立的情况下,反复执行某一段代 ...

  9. AE加载不同数据的方法(GeoDatabase空间数据管理)

    原文 AE加载不同数据的方法(GeoDatabase空间数据管理) GeoDatabase 先看一下GeoDatabase核心结构模型图: 1  工作空间工厂WorkspaceFactory对象 Wo ...

  10. [RxJS] AsyncSubject: representing a computation that yields a final value

    This lesson will teach you about AsyncSubject, another type of Subject with some replaying logic ins ...