学习随笔-关于getchar(),EOF和[Ctrl+Z]
一、getchar()
getchar()由宏实现:#define getchar() getc(stdin)。
当程序调用getchar()时,程序就等着用户按键。 用户输入的字符被存放在键盘缓冲区(用来缓存“按键”的ASCII码)中,直到用户按[回车]为止。 当用户键入[回车]之后,getchar()才开始从stdin流中每次读入一个字符。
getchar()函数的返回值是用户输入的字符的ASCII码,若到达文件末尾或出错,则返回-1(EOF)。 getchar()还会将用户输入的字符回显到屏幕。 如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar()调用读取。 也就是说,后续的getchar()调用不会等待用户按键,而是直接读取缓冲区中的字符,直到缓冲区中的字符读完后,才等待用户按键。
getch
getch()与getchar()基本功能相同,差别是getch()直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch()就立刻返回,getch()返回值是用户输入的ASCII码,出错返回-1,输入的字符不会回显在屏幕上。
getch()函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用getch()函数暂停程序运行,当按任意键后程序继续运行。
Δ什么情况是出错?
二、EOF
EOF在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。
在while循环中以EOF作为文件结束标志(终端输入时,windows系统中是[Ctrl+Z],linux系统是[Ctrl+D]),这种以EOF作为文件结束标志的文件,必须是文本文件。 在文本文件中,数据都是以字符的ASCII代码值的形式存放。
一般在C/C++中EOF是个宏定义,其值为-1,也就是说,EOF并不是个字符,没有什么特殊的结构,只是一个值为-1的宏定义而已。(不同的平台,EOF的值可能不同) 我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。
引入几个定义:
流
“流”:是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。
缓冲区
缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲。
全缓冲:
在这种情况下,当 填满 标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是 对磁盘文件的读写 。
行缓冲:
在这种情况下,当在输入和输出中遇到 换行符 时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等 按下回车键换行 时才进行实际的I/O操作。典型代表是 标准输入(stdin) 和 标准输出(stdout) 。
不带缓冲:
也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。
下列情况会引发缓冲区的刷新:
缓冲区满时 ; 行缓冲区遇到回车时 ; 关闭文件 ; 使用特定函数刷新缓冲区 。
检查方式——阻塞式和非阻塞式
阻塞式检查方式指的是只有在回车键按下之后才对此前是否有[Ctrl+Z]组合键按下进行检查;
非阻塞式样指的是按下[Ctrl+D]之后立即响应的方式(如果在按[Ctrl+D]之前已经从键盘输入了字符,则[Ctrl+D]的作用就相当于回车(但是回车自己也会进入缓冲),即把这些字符送到输 入缓冲区供读取使用,此时[Ctrl+D]不再起流结束符的作用。如果按[Ctrl+D]之前没有任何键盘输入,则[Ctrl+D]就是流结束的信号。)。
Windows系统中一般采用阻塞式检查[Ctrl+Z]、Unix/Linux系统下一般采用非阻塞式的检查[Ctrl+D]。
三、[Ctrl+Z]
[Ctrl+Z]即^Z,该符号在ASCII中是有对应的,值是26,也就是说键入[Ctrl+Z]后,可能输入的是一个ASCII值为26的字符。 此外,[Ctrl+Z]在Windows系统中还用来标志流结束。
输入缓冲就是行缓冲,所以当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。 每当按下回车键后,就会检测输入缓冲区中是否有可读的数据(当缓冲区中含有可读数据时,[Ctrl+z]就不是结束标志了,而是作为^Z字符输入),还会对键盘上是否有作为流结束标志的[Ctrl+Z]或者[Ctrl+D]键 按下作出检查。
也就是说,只有[Ctrl+Z]前面是[回车]时,[Ctrl+Z]才会作为流结束的标志,此时,getchar()读取出错,返回DOF(-1);否则会输出特殊符号。