详解while((ch = getchar()) != EOF)
问题
博主在学习C语言的过程中,遇到了这么一条语句
int ch;
while((ch = getchar()) != EOF) putchar(ch);
其运行如下图所示
第一行是我的键盘输入:I love UJS
第二行是我的程序输出:I love UJS
认真学过C语言的同学应该知道,getchar()仅能接收一个字符,putchar也是如此,在我看来程序的输出不应该是I love UJS
,而应该是I
,因为这两个函数仅能接收一个字符,其他的字符会统统扔掉。
下面我们就来解释一下,为什么putchar()可以输出一个字符串。
知识背景
在解决之前我们先来了解一下什么是缓冲输入,无缓冲输入,以及流结束符EOF
无缓冲输入:用户输入字符后,程序立刻将这个字符打印出来,比如
II JJUU LL NN UUaa AAFFEEIILLOOVVEEYYOOUU
像这样,出现了字符的回显,即输入一个字符马上打印一个字符,这个过程成为无缓冲输入
缓冲输入:用户输入字符后,字符会存入一个缓冲区中,直到用户按下Enter键,才会打印缓冲区的字符,其优点是用户可以修改输入内容,增删减改。当然,其缺点是必须要按下Enter键才能输出内容,不如无缓冲输入及时,比如在很多电子游戏中就是采用的无缓冲输入(如CS的WASD,英雄联盟的QWER)。
流结束符EOF:在编程的世界中,输入不仅仅是键盘输入,还有文件输入,流媒体输入等等一系列的输入,那么计算机是如何来判定程序输入的结束呢?很多同学认为按下Enter键不就结束输入了么?这是错误的,因为我们已经说了输入有各种各样的形式,里面也不会帮你按下Enter键。所以,我们需要一个字符,一个任何文件都不会用到的字符----EOF(End Of File)。EOF定义在stdio.h文件中:
#define EOF (-1)
为什么是-1
?因为getchar()函数虽是int类型,但返回值通常都介于0~127,也就是ASCII码的范围,因此-1
这个字符不会对应任意一个字符,所以它可以作为文件结尾的标志,用来结束文件的输入。在Windows系统中,用户可以通过Ctrl+Z
来表示EOF,以结束文本流的输入。
解决问题
了解完以上内容,我们回到我们的代码:
int ch;
while((ch = getchar()) != EOF) putchar(ch);
这里我们定义了一个整型变量ch,为什么不是字符型变量,因为字符型变量是无符号的,无法把-1这个值赋给字符型变量。
接下来进入我们的while循环,首先先输入一个字符,判断这个字符是否是EOF字符,若不是,则执行putchar(),此时用户输入的字符存储在缓冲区中,但没有按下Enter
键,那么程序即使执行到putchar(),也不会将这个字符打印出来,因为压根就没有刷新缓冲区(笑),当用户按下Enter
键之后,计算机刷新缓冲区,将这个缓冲区的内容打印出来。
这里可能有的同学就问了:诶?putchar只能打印一个字符,那即使刷新了缓冲区,putchar()也只能打印一个字符啊
这句话确实没错,但是博主在这里需要强调一下,无论是printf还是putchar,其本质都是一样的,都是刷新缓冲区,将缓冲区的内容打印出来,而我们在普通的putchar的适合,是getchar,再putchar,而getchar的时候就已经输入Enter键,即刷新缓冲区,因此输出一个字符。这点各位同学一定要理解清楚啊。
如果解决了你的问题,请帮忙点个赞,谢谢大家哦~~
博主QQ:2240172425,可以加博主QQ一起交流学习经验
若是出现错误,还请大家海涵。
详解while((ch = getchar()) != EOF)相关推荐
- getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析...
2013-07-18 21:35:58 getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析. char是字符型数 ...
- 【C标准库】详解feof函数与EOF
创作不易,多多支持! ‾ \underline{创作不易,多多支持! } 创作不易,多多支持! 再说此函数之前,先来说一下EOF是什么 EOF,为End Of File的缩写,通常在文本的最后存在此 ...
- C语言中getchar()函数的详解
文章目录 关于getchar()函数的基本作用 getchar()函数基本案例 在循环当中的getchar() getchar()函数的作用 清理缓冲区中多个字符 关于getchar()函数的基本作用 ...
- getchar函数与其在缓存区的使用(详解易懂)---读取多组值:scanf返回值的理解使用
文章目录 前言 1.scanf返回值的应用 1.判断一个人是否为天才? 1.1==scanf返回值的认识== 2.判断两个数的大小关系 2.getchar在缓存区的使用 2.1了解getchar,pu ...
- C语言getchar的用法详解
getchar getchar的定义 MSDN中的解释是从流中读取一个字符 int ch = getchar() //通过getchar获取字符的ASCII码值传到ch里面存储 这里注意:getcha ...
- continue 的用法详解
continue 的用法详解 continue用法 continue 的用法详解 continue 在while中的用法 continue 在for中的用法 continue 在剔除多余元素的用法 c ...
- C语言操作符详解 隐式类型转换 (整型提升 算数转换)
目录 一.算术操作符 二.左移操作符 右移操作符 1.二进制序列 2.左移操作符 3.右移操作符 3.1.逻辑运算/算术运算 3.2.对于移位运算符,不要移动负数位,这是标准未定义的 3.3.对于移位 ...
- while((ch=getchar())!=EOFch != '\n');消除非法输入
第一个程序接收用户输入的两个整数并打印 #include <stdio.h> int main() {int a, b;printf("请输入两个正整数:\n");sc ...
- 有限状态机详解(转载)
以前总觉得有限状态机和无限状态机非常的难理解,原来也就是自己一直没有一个直观的认识,今天看到一篇博客,总算对有限状态机入门了.一看就懂. 转载地址:http://blog.csdn.net/zqixi ...
最新文章
- 2022-2028年中国铁路行业投资分析及前景预测报告(全卷)
- 提取ESX/ESXI4.0脚本安装文件ks.cfg、ks-first.cfg和ks-first-safe.cfg
- 爬取微博对话语料制作聊天机器人
- sparksql dataframe变成csv保存_Spark大数据分析(三):DataFrame和SQL
- datagrip中sqlite3导入csv数据集
- layui table工具栏点击时间_layui table表格上添加日期控件laydate
- Hibernate入门这一篇就够了
- 长城 宽带 +招商银行专业版
- [sql]匹配标题中出现最多关键字的结果
- linux 线程异常退出_Linux 进程必知必会
- ^全^ 获取SQL SERVER2000/2005、MySql、Oracle元数据的SQL语句 [SQL语句来自CodeSmith]
- 用伪代码梳理springcloud
- 小型迷宫实现---迷宫算法(递归回溯法)
- Pycharm使用小Tips
- 懒癌发作,福利直接发,不抢白不抢!
- window文件批量转换 cwp批量转换jpg
- c++游戏编程初步(超简单)教学
- 浅谈Deferred(延迟对象)
- 3年车载测试人员的经验总结分享
- fpu测试_解毒盖世G600散热器,3900X超频测试能不能压住?