[转载]C语言EOF是什么?
原贴网址:http://www.kuqin.com/language/20111112/314745.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,连续输入两次就行了。
(完)
[转载]C语言EOF是什么?的更多相关文章
- C语言EOF是什么?
C语言 EOF是什么? Linux中,在新的一行的开头,按下Ctrl-D,就代表EOF(如果在一行的中间按下Ctrl-D,则表示输出"标准输入"的缓存区,所以这时必须按两次Ctrl ...
- [转载]ecmall语言包程序
[转载]ecmall语言包程序 (-- ::) 转载▼ 标签: 转载 收藏了 原文地址:ecmall语言包程序作者:我思故我在 执行顺序 登陆后台后 最先执行的文件是 default.app.php ...
- 转:c语言EOF是什么?(及getchar()和putchar用法)
我学习C语言的时候,遇到的一个问题就是EOF. 它是end of file的缩写,表示"文字流"(stream)的结尾.这里的"文字流",可以是文件(file) ...
- C语言EOF
验证表达式getchar()!=EOF的值是1还是0 编写一个打印EOF值的程序 windows下是ctrl-z 就是ctrl和z一起按了,就是结束符linux下是ctrl-d是结束符.这个是一个 ...
- [转载]C语言头文件的作用
最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学 习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是 ...
- (转载)Go语言开发环境配置
一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...
- [转载] Go语言并发之美
原文: http://qing.blog.sina.com.cn/2294942122/88ca09aa33002ele.html 简介 多核处理器越来越普及,那有没有一种简单的办 ...
- (转载)c语言指针学习
前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...
- 基于C语言EOF与getchar()的使用详解
转自:http://www.jb51.net/article/36848.htm 大师级经典的著作,要字斟句酌的去读,去理解.以前在看K&R的The C Programming Langu ...
随机推荐
- 【默默努力】fishingGame
这个捕鱼游戏挺有意思的,通过发射子弹,打鱼.打鱼的子弹会消耗金币,但是打鱼如果打到了鱼,就会奖励金币的数量. 我如果写这个的话,应该会画一个 背景海底,然后生成很多鱼的图片,还要有一个大炮,金币.大炮 ...
- 关于IOC
1. [调侃]IOC前世今生 http://www.cnblogs.com/showjan/p/3950989.html#!comments 2. 使用ConfigurationManager类 读写 ...
- 【Uva 12128】Perfect Service
[Link]: [Description] 给你n个机器组成的一棵树,然后,让你在某些机器上安装服务器. 要求,每个机器如果没有安装服务器,都要恰好和一个安装了服务器的机器连接. 问你,最少要安装多少 ...
- VUE下echarts宽度响应式
window.addEventListener("resize", () => { myChart2.resize();});
- java多线程编程建议
多线程编程建议 1,将应用设计成支持多线程并发,可提高性能 2,编写多线程程序,首先保证它是正确的,其次再考虑性能 3,同步处理的开销大于非同步处理,如果可能,尽量使用非同步处理 4,避免多个共享变量 ...
- <爬虫>用正则爬取B站首页图片
import re import requests headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Apple ...
- <数据库>MySQL的安装及安装中存在的问题
无脑三连: 下载:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 解压:任意目录 添加环境变量:WIN10步骤 我的电脑→属性→高级系 ...
- Linux常用知识
1.Redhat 系统按如下系统启动:加载内核执行init程序/etc/rc.d/rc.sysinit #由init执行的第一个脚本/etc/rc.d/rc${RUNLEVEL}d/* #$RUNLE ...
- 2019-8-31-dotnet-如何在-Mock-模拟-Func-判断调用次数
title author date CreateTime categories dotnet 如何在 Mock 模拟 Func 判断调用次数 lindexi 2019-08-31 16:55:58 + ...
- JZOJ2368 【SDOI2011】黑白棋
题目 题目大意 在一个1*n的棋盘上,有黑棋和白棋交错分布,每次,一个人可以移动自己的ddd颗旗子. 问先手必胜的方案数. 思考历程 在一开始,我就有点要放弃的念头. 因为这题是一道博弈问题. 我是非 ...