问题

博主在学习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)相关推荐

  1. getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析...

    2013-07-18 21:35:58 getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析. char是字符型数 ...

  2. 【C标准库】详解feof函数与EOF

    创作不易,多多支持! ‾ \underline{创作不易,多多支持! } 创作不易,多多支持!​ 再说此函数之前,先来说一下EOF是什么 EOF,为End Of File的缩写,通常在文本的最后存在此 ...

  3. C语言中getchar()函数的详解

    文章目录 关于getchar()函数的基本作用 getchar()函数基本案例 在循环当中的getchar() getchar()函数的作用 清理缓冲区中多个字符 关于getchar()函数的基本作用 ...

  4. getchar函数与其在缓存区的使用(详解易懂)---读取多组值:scanf返回值的理解使用

    文章目录 前言 1.scanf返回值的应用 1.判断一个人是否为天才? 1.1==scanf返回值的认识== 2.判断两个数的大小关系 2.getchar在缓存区的使用 2.1了解getchar,pu ...

  5. C语言getchar的用法详解

    getchar getchar的定义 MSDN中的解释是从流中读取一个字符 int ch = getchar() //通过getchar获取字符的ASCII码值传到ch里面存储 这里注意:getcha ...

  6. continue 的用法详解

    continue 的用法详解 continue用法 continue 的用法详解 continue 在while中的用法 continue 在for中的用法 continue 在剔除多余元素的用法 c ...

  7. C语言操作符详解 隐式类型转换 (整型提升 算数转换)

    目录 一.算术操作符 二.左移操作符 右移操作符 1.二进制序列 2.左移操作符 3.右移操作符 3.1.逻辑运算/算术运算 3.2.对于移位运算符,不要移动负数位,这是标准未定义的 3.3.对于移位 ...

  8. while((ch=getchar())!=EOFch != '\n');消除非法输入

    第一个程序接收用户输入的两个整数并打印 #include <stdio.h> int main() {int a, b;printf("请输入两个正整数:\n");sc ...

  9. 有限状态机详解(转载)

    以前总觉得有限状态机和无限状态机非常的难理解,原来也就是自己一直没有一个直观的认识,今天看到一篇博客,总算对有限状态机入门了.一看就懂. 转载地址:http://blog.csdn.net/zqixi ...

最新文章

  1. 2022-2028年中国铁路行业投资分析及前景预测报告(全卷)
  2. 提取ESX/ESXI4.0脚本安装文件ks.cfg、ks-first.cfg和ks-first-safe.cfg
  3. 爬取微博对话语料制作聊天机器人
  4. sparksql dataframe变成csv保存_Spark大数据分析(三):DataFrame和SQL
  5. datagrip中sqlite3导入csv数据集
  6. layui table工具栏点击时间_layui table表格上添加日期控件laydate
  7. Hibernate入门这一篇就够了
  8. 长城 宽带 +招商银行专业版
  9. [sql]匹配标题中出现最多关键字的结果
  10. linux 线程异常退出_Linux 进程必知必会
  11. ^全^ 获取SQL SERVER2000/2005、MySql、Oracle元数据的SQL语句 [SQL语句来自CodeSmith]
  12. 用伪代码梳理springcloud
  13. 小型迷宫实现---迷宫算法(递归回溯法)
  14. Pycharm使用小Tips
  15. 懒癌发作,福利直接发,不抢白不抢!
  16. window文件批量转换 cwp批量转换jpg
  17. c++游戏编程初步(超简单)教学
  18. 浅谈Deferred(延迟对象)
  19. 3年车载测试人员的经验总结分享
  20. fpu测试_解毒盖世G600散热器,3900X超频测试能不能压住?

热门文章

  1. Kernel: XFS
  2. XFS文件系统文件恢复与备份
  3. 2023秋招英特尔Intel 软件/FPGA真题回忆录
  4. Java实习生面试题整理
  5. 电商离线数仓项目实战(下)
  6. 【深度学习】——神经网络中常用的激活函数:sigmoid、Relu、Tanh函数
  7. GPT-4发布!ChatGPT大升级!
  8. 10.查询没有学全所有课的同学的学号、姓名
  9. linux dhcp 服务失败,Centos7安装及配置DHCP服务,安装程序配置服务失败
  10. Centos7下Mysql添加用户并进行授权