什么是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> < ...
随机推荐
- Scrum 冲刺博客链接集合
DAY1 http://www.cnblogs.com/qiaokeliweibaba/p/8901187.html DAY2 http://www.cnblogs.com/qiaokeliweiba ...
- 字符串经过base64编码后的长度与原字符串的长度是什么关系呀?
beforeEncode为Encode之前的字符串 那么Encode后的字符串长度为: 1.如果beforeEncode.length()是3的整数倍,那么长度为 (beforeEncode.len ...
- windows下python3.6安装pycryto or crypto or pycryptodome与使用
pycrypto,pycrytodome和crypto是一个东西,在很久以前,crypto在python上面的名字是pycrypto它是一个第三方库,但是已经停止更新三年了,所以不建议安装这个库: w ...
- PHP-时间函数
1.时间格式化函数date(format,timestamp) format 时间格式 timestamp 时间戳 下面列出了一些常用于日期的字符: d - 表示月里的某天(01-31) m - 表示 ...
- go 面试题总结
1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...
- HDU4622_Reincarnation
题目给出一个长为2000的字符串,和10000询问,每次询问从第l到第r个字符中间有多少个不同的子串. 其实,全部预处理.f[i][j]表示从i到j个字符的子串数.重构2000遍SAM. 对于新加入的 ...
- BZOJ5127 数据校验
第一眼看错题以为只是要求区间值域连续,那莫队一发维护形成的值域段数量就行了. 原题这个条件相当于区间内相邻数差的绝对值不超过1.所以只要对这个做个前缀和就……完了? #include<iostr ...
- 【BZOJ4140】共点圆加强版(二进制分组)
[BZOJ4140]共点圆加强版(二进制分组) 题面 BZOJ 题解 我卡精度卡了一天.... 之前不强制在线的做法是\(CDQ\)分治,维护一个凸壳就好了. 现在改成二进制分组,每次重建凸壳就好了. ...
- BZOJ2530 [Poi2011]Party 【贪心】
题目链接 BZOJ2530 题解 如果我们删去一对不连边的仍然存在的点的话,这对点肯定不同时在那个\(\frac{2}{3}n\)的团中,也就是说,每次删点至少删掉一个外点,至多删掉一个内点 那么我们 ...
- 【bzoj3527】 Zjoi2014—力
http://www.lydsy.com/JudgeOnline/problem.php?id=3527 (题目链接) 题意 $${F_i=\sum_{j<i} {\frac{q_iq_j}{( ...