EOF是什么?
转自http://www.ruanyifeng.com/blog/2011/11/eof.html
学习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是什么?的更多相关文章
- linux下EOF写法梳理
在平时的运维工作中,我们经常会碰到这样一个场景:执行脚本的时候,需要往一个文件里自动输入N行内容.如果是少数的几行内容,还可以用echo追加方式,但如果是很多行,那么单纯用echo追加的方式就显得愚蠢 ...
- php定界符<<<EOF讲解(转)
Heredoc技术.可用来输出大段的html和javascript脚本 1.PHP定界符的作用就是按照原样,包括换行格式什么的,输出在其内部的东西: 2.在PHP定界符中的任何特殊字符都不需要转义: ...
- while(cin.eof)出错 poj
zoj遇到c++如何判定输入流结尾的问题,一不小心就超时了 楼下的代码可以通过zoj #include<iostream> using namespace std; int main(){ ...
- c++ eof()函数
C++ eof()函数可以帮助我们用来判断文件是否为空,抑或是判断其是否读到文件结尾.在这里我们将会对其进行详细的介绍. C++编程语言中的很多功能在我们的实际应用中起着非常大的作用.比如在对文件文本 ...
- 【转】 解读EOF
解读EOF 标签: fplinuxc语言filestream 2012-01-31 22:05 439人阅读 评论(0) 收藏 举报 分类: C.C++_程序设计(20) 我学习C语言的时候,遇到 ...
- Linux C 字符函数 getchar()、putchar() 与 EOF 详解
首先给出<The_C_Programming_Language>这本书中的例子: #include <stdio.h> int main() { int c; c = getc ...
- Ext3文件系统mount选项和文件属性介绍
mount选项 设置方式 ext3 mount选项可以通过多个方式进行设置:1)内核编译时: 内核menuconfig通过CONFIG_EXT3_DEFAULTS_TO_ORDERED编译控制选项,来 ...
- .NET 串口通信中断接收,包含0X1A(作为EOF)
.NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...
- 常见的getchar 与EOF的问题
代码中常有类似的如下的输入循环 char c; while((c=getchar())!=EOF).... 如果输入 字符+换行时,循环的代码会执行两次,主要是换行键作为字符存到了缓存队列中,第一次 ...
- PHP eof的使用
PHP eof的使用 也就是heredoc技术,来部分实现界面与代码的分离 <?php $name = '张三'; print <<<EOT <html> < ...
随机推荐
- vm虚拟机上安装apache+php+ftp+mysql
我在vm虚拟机上想安装 winxp和linux,然后在linux机上装apache+php+ftp+mysql,以下为我的按装过程: 1:连通虚拟机:两个虚拟机都选Host-Onl,查看主机Virt ...
- yum kvm
---恢复内容开始--- 1. 安装软件包: yum -y install virt-manager; yum install qemu-kvm yum install libvirt yum ...
- 【转】sublime text 2 下的Markdown写作
sublime text 2 下的Markdown写作 作为Windows/Mac/Linux下强大的文本编辑器,st提供了对Markdown语言的支持.通过设置可实现markdown预览和转换功 ...
- Python队列服务 Python RQ Functions from the __main__ module cannot be processed by workers.
在使用Python队列服务 Python RQ 时候的报错: Functions from the __main__ module cannot be processed by workers. 原因 ...
- Ⅹ.spring的点点滴滴--IObjectPostProcessor(对象后处理器)
承接上文 IObjectPostProcessor(对象后处理器) 前提是实现接口的对象注册给当前容器 C#: 通过继承AbstractObjectFactory对象的AddObjectPostPro ...
- Kinect for Windows SDK开发入门(一):开发环境配置
[译]Kinect for Windows SDK开发入门(一):开发环境配置 前几天无意中看到微软发布了Kinect for windows sensor,进去看了一下Kinect应用的例子,发现K ...
- 使用HttpClient进行http post/get方法的调用,以及使用dom4j解析xml
import java.io.IOException; import java.util.List; import javax.servlet.ServletInputStream; import j ...
- Redis学习手册(实例代码)
在之前的博客中已经非常详细的介绍了Redis的各种操作命令.运行机制和服务器初始化参数配置.本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例. ...
- MYSQL----myownstars(102)
http://blog.itpub.net/15480802/cid-84815-list-1/
- careercup-树与图 4.8
4.8 你有两棵非常大的二叉树:T1,有几百万个结点:T2,有几百个结点.设计一个算法,判断T2是否为T1的子树. 如果T1有这么一个结点n,其子树与T2一模一样,则T2C++实现代码: #inclu ...