EOF是什么
我学习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,连续输入两次就行了。
http://www.ruanyifeng.com/blog/2011/11/eof.html
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> < ...
随机推荐
- 问题:org.hibernate.LazyInitializationException: failed to lazily initialize
今天搞了一上午,都在解决这个问题:org.hibernate.LazyInitializationException: failed to lazily initialize 原因很简单,是在非法的s ...
- tcpdump/HTTP协议实践
tcpdump/HTTP协议实践 客户端: CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAI ...
- oracle connect by 递归,反递归,自动补全查询实现
递归: select * from t_pams_solution t start with t.id is null connect by prior id = t.parent_id ...
- linux文件字符集转换(utf8-gb2312)
一,命令行 在LINUX上进行编码转换时,可以利用iconv命令实现,这是针对文件的,即将指定文件从一种编码转换为另一种编码. iconv命令用法如下:iconv [选项...] [文件...] 1. ...
- 【C#】 创建、部署和调用WebService的简单示例
C# 创建.部署和调用WebService的简单示例 <div class="postBody"> <div id="cnblogs_post_body ...
- 继承&多态
继承: 概念: 基类,超累,父类 访问权限: Public :无限制,自由访问 Private:不可继承 protected :包内,包外,可访问,继承 default:没有指明任何权限下,默认在同一 ...
- DevExpress ASP.NET Dev控件客户端事件 ClientSideEvents
原文地址:http://www.cnblogs.com/allenlf/p/4171189.html
- ADX3000二层的负载均衡设计问题
我的想法是 想在现有的局域网内部,利用ADX划分出一个新的局域网,模拟负载均衡. 现在有三台试验机器,拓扑图如下: 各个机器IP设置如下图: 我进行了如下的操作: 1 在组网配置当中,设置eth1_0 ...
- jq表单验证
<body> <form method="post" action=""> <div class="int"& ...
- 树链剖分【洛谷P1505】 [国家集训队]旅游
P1505 [国家集训队]旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城 ...