单字符的I/O(getchar、putchar)& Shell中的缓冲区
知识铺垫:EOF
EOF 就是个 int 宏常量,表示 end-of-file,文档中有下面这么一段话:
阮一峰老师也讲过:EOF是什么?
1 | char ch; |
本图可点击
单字符的I/O
假设我想读入单个字符,该怎么办呢 ?=> 用getchar()
假设我想输出单个字符,该怎么办呢 ?=> 用putchar()
当然你可以可用 scanf() 和 printf(),并使用 %c
1 | char ch; |
关于 getchar() 的返回值是 int 这件事
文档中有下面这么一段话:
举个例子
1 | char ch; |
这段代码的执行结果十分神奇
在命令行中,编译执行这段程序,命令行就会等待你用键盘输入内容,这符合预期
但接下来发生的事情可能就会和你的想法不太一样了
首先,你可以连续敲击键盘进行输入,只有当你按下「回车」,命令行才会有所回应
它会将你输入的内容原封不动地输出到你的显示屏上(就像 echo
一样)
接下来,你的命令行会继续等待你用键盘输入内容,并会如此循环往复
如果想停掉这个程序,你只能 ^C(你输入 EOF 或 -1 都不行),但并不会输出代码最后一行的 EOF
这说明我们并没有正确地输入 EOF,也就并没有让我们的程序知道「输入结束」这件事情,我们只是在程序运行的中途就直接强制退出了该程序
那如何向 Shell 输入 EOF ?
Unix(Linux):^D
DOS(Windows):^Z
要理解上面这段程序背后发生了什么,我们必须了解一些关于 Shell 和其中的缓冲区的知识
Shell
键盘/显示器 <= Shell => 应用程序
Shell 是一个特殊的程序,它能将你的程序 run 起来,也能将运行着的程序 kill 掉
当 Shell 监听到用户按下了 ^C,运行着的程序就被 kill 掉了…
Shell 中的缓冲区
当用户在命令行中编译执行上面那段程序时,Shell 会负责将其 run 起来
不难看出程序会停在 getchar()
,等待用户敲击键盘进行输入
比如你输入了一个字符 a,其实这个字符并没有被立刻送入你的应用程序,而是先被送到了 Shell 那里
Shell 会将收到的字符放在自己的缓冲区中,'\0'
是缓冲区内容末尾的标志,就像下图这样
由于此时 Shell 并没有接收到(回车符 || EOF),所以 Shell 会继续等待用户的输入(应用程序此时并不读取 Shell 的缓冲区中的内容)
假设你又输入了两个字符 b 和 c,缓冲区就变成了下面这个样子
一旦你按下了「回车」,你的应用程序就会开始从 Shell 的缓冲区中读取内容(刚按下回车的缓冲区就像下面这样)
上面那段程序中,getchar()
逐个字符地读取,读一个字符就输出一个字符
一旦读到 \0
就说明读到了缓冲区的末尾,对于上面那段程序,由于此时还没有读到 EOF,所以 while 循环会继续,也就会继续停在 getchar()
等待用户的输入
当用户按下了 ^D,Shell 的缓冲区就会收到信号 EOF,此时你的应用程序立刻就会读到 EOF
对于上面那段应用程序,不难看出就跳出了 while 循环,继续向下执行,直到程序全部执行结束,正常退出。
另外:缓冲区也可以从文件中读取内容
(完)