getchar 和EOF
本文章基于:http://www.cnblogs.com/QLinux/articles/2465329.html,稍作了修改。
大师级经典的著作,要字斟句酌的去读,去理解。以前在看K&R的The C Programming Language(Second Edition)中第1.5节的字符输入/输出,很迷惑getchar()和EOF的行为。因此,感觉很有必要总结一下,不然,很多琐碎的知识点长时间过后就会淡忘的,只有写下来才是最好的方法。
一、对getchar的两点总结:
1. getchar是以行为单位进行存取的。
当调用getchar函数读取输入时,只有当输入字符为换行符'/n'或文件结束符EOF时,getchar才会停止执行,整个程序将会往下执行。并且,如果输入行是以EOF结束的(EOF之前不是换行符),则EOF会被“吃掉”(即不会被getchar读取到)。譬如下面程序段:
while((c = getchar()) != EOF){
putchar(c);
}
执行程序
输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc和一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把 那一行的输入的字符输出在终端上。
输入:abc,然后执行ctrl+d,则程序执行putchar(c),然后输出abc。(此处ctrl+d和回车具有一样的功能)。
令人迷惑的是,getchar不是以字符为单位读取的吗?那么,既然我输入了第一个字符a,肯定满足while循环(c = getchar()) != EOF的条件,那么应该执行putchar(c)在终端输出一个字符a。但是程序就偏偏不这样执行,而是必需读到一个换行符或者文件结束符EOF才进行一次输出。
造成这种结果的一种解释是,输入终端驱动处于一次一行 的模式下。也就是虽然getchar()和putchar()确实是按照每次一个字符进行的。但是终端驱动处于一次一行的模式,它的输入只有到'/n'或 者EOF时才结束。在本例中,程序段调用了getchar函数,则控制权从程序段转移到getchar函数,而getchar函数要依赖于操作系统的驱动 来读取输入,没遇到换行符或者EOF,驱动不会通知getchar函数,getchar函数处于“阻 塞”状态。而遇到换行符或者EOF后,getchar函数解除“阻塞”,读取一个字符,控制权返回程序段,执行putchar函数,循环执行。直到遇到EOF字符或者这行输入全部处理完。
2. getchar()的返回值一般情况下是非负 值,但也可能是负值,即返回EOF。EOF在函数库里一般定义为-1。正确的定义方法如下(K&R C中特别提到了这个问题):
int c;
c = getchar();
//原因忘了...
二、EOF的两点总结(主要指普通终端中的EOF)
1. EOF作为文件结束符时的情况:
EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。
(1)遇到getcahr函数执行时,要输入第一个字符时就直接输入Ctrl+D;
(2)在前面输入的字符为换行符时, 接着输入Ctrl+D;
(3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第二次输入的Ctrl+D起到文件结束符的功能,至于第一次的
Ctrl+D作为行结束符(如1.1所讲)。
其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时, 直接输入Ctrl+D才相当于文件结束符。
2. EOF作为行结束符时的情况,这时候输入Ctrl+D作为行结束的标志能结束getchar()的“阻塞”,使getchar()逐个字符读入,但是EOF会被“吃掉”,并不会被读取。
以上面的代码段为例, 如果执行时输入abc,然后 Ctrl+D,程序输出结果为:
abcabc
注意:第一组abc是你从终端输入的,然后输入Ctrl+D,getchar逐个字符读取并逐个输出打印出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,就会起到了文件结束符的作用,因为EOF是一行输入的第一个字符。如果输入abc之后,然后回车,输入换行符的话,则终端显示为:
abc'/n'
abc'/n'
//第三行
其中第一行为你终端输入的,第二行是终端输出(含换行符),光标停在了第三行处,等待新一次的终端输入。从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。
getchar 和EOF的更多相关文章
- getchar()与EOF
大师级经典的著作,要字斟句酌的去读,去理解.以前在看K&R的The C Programming Language(Second Edition)中第1.5节的字符输入/输出,很迷惑getcha ...
- 常见的getchar 与EOF的问题
代码中常有类似的如下的输入循环 char c; while((c=getchar())!=EOF).... 如果输入 字符+换行时,循环的代码会执行两次,主要是换行键作为字符存到了缓存队列中,第一次 ...
- Linux C 字符函数 getchar()、putchar() 与 EOF 详解
首先给出<The_C_Programming_Language>这本书中的例子: #include <stdio.h> int main() { int c; c = getc ...
- 基于C语言EOF与getchar()的使用详解
转自:http://www.jb51.net/article/36848.htm 大师级经典的著作,要字斟句酌的去读,去理解.以前在看K&R的The C Programming Langu ...
- getchar() 和 scanf("%c")的区别
getchar()和scanf("%c")的功能都是从STDIN读一个字符,单论功能两者没有区别. 但两者的返回值是有区别的: -------------------------- ...
- getchar
getchar函数每次只从缓冲区中接受一个字符. getchar有一个int型的返回值. 当程序调用getchar时,程序就等着用户按键,用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止(回车字 ...
- 关于文件结束符EOF
EOF 是 End Of File 的缩写. 在 C 语言中,它是在标准库中定义的一个宏. 人们经常误认为 EOF 是从文件中读取的一个字符(牢记).其实,EOF 不是一个字符,它被定义为是 int ...
- HDU2047 阿牛的EOF牛肉串
题目:https://blog.csdn.net/qq_40932661?t=1 表面上看去似乎无从下手.但是可以从前面地推出后面的 递推: 假如涂第N个位置,有两种可能,①涂O ②不涂O. 如果涂O ...
- getchar返回int类型
#include <stdio.h> /* copy input to output; 2nd version */main(){int c;c = getchar();while(c ! ...
随机推荐
- idea 中 下载源码:Sources not download for:
使用idea 下载源码出现:Sources not found for: 解决方案:在对应的pom.xml 文件中打开 terminal,执行 mvn命令: mvn dependency:source ...
- 前端开发 Vue -4promise解读1
JS(JavaScript) - Promise 2015年6月, ES2015(即 ECMAScript 6.ES6) 正式发布.其中 Promise 被列为正式规范,成为 ES6 中最重要的特性之 ...
- python学习笔记(CMD运行文件并传入参数)
好久没更新博客了 最近换了份新工作 有时间来整理一篇 在命令行CMD中执行文件过程中如何传入并识别参数 # -*- coding: utf-8 -*- # CMD运行类 # 作者: # 时间: 201 ...
- SAP Cloud for Customer的Container应用设计原理
来自Jerry的同事,Yang Joey. 相信大部分C4C的UI developer包括我刚开始的时候都会比较好奇我们平时写的javascript代码是如何运行在移动设备上的,同样的,我也对这个问题 ...
- 【SpringMVC】统一异常处理
一.需求 二.统一异常处理解决方案 2.1 定义异常 2.2 异常处理 2.3 配置统一异常处理器 2.4 异常处理逻辑 一.需求 一般项目中都需要作异常处理,基于系统架构的设计考虑,使用统一的异常处 ...
- DNS服务——域名解析转发 和 条件转发
前言 有一台Linux机器作为DNS服务器,查看这台机器上的DNS文件,发现指向互联网上的DNS服务器. [root@ziqiang named]# cat /etc/resolv.conf # Ge ...
- sudo 权限的管理
一.sudo执行命令的流程将当前用户切换到超级用户下,或切换到指定的用户下,然后以超级用户或其指定切换到的用户身份执行命令,执行完成后,直接退回到当前用户.具体工作过程如下:当用户执行sudo时,系统 ...
- iptables详解(5)iptables的icmp扩展
ICMP(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议簇的一个子协议,用于在IP主机.路由器之间传递控制消息.控制消息是指网络 ...
- Linux网络编程综合运用之MiniFtp实现(五)
转眼兴奋的五一小长假就要到来了,在放假前夕还是需要保持一颗淡定的心,上次中已经对miniFTP有基础框架进行了搭建,这次继续进行往上加代码,这次主要还是将经历投射到handle_child()服务进程 ...
- 【转】Senior Data Structure · 浅谈线段树(Segment Tree)
本文章转自洛谷 原作者: _皎月半洒花 一.简介线段树 ps: _此处以询问区间和为例.实际上线段树可以处理很多符合结合律的操作.(比如说加法,a[1]+a[2]+a[3]+a[4]=(a[1]+a[ ...