EOF和ctrl+z

先来看一下如下代码以及运行结果:

#include
#include

#include

int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}
system("pause");
return 0;

}

EOF和ctrl+z_第1张图片

很明显,以上代码可以实现:当用户输入一个字符时,便会自动输出这个字符,当用户不想输入时可使用ctrl+z(^Z)结束

那么接下来这个运行结果是怎么回事呢?

EOF和ctrl+z_第2张图片

输入字符串"abcdef"按原样输出。输入字符串"abcdef"+ctrlz,按道理应该输出"abcdef"然后结束程序。(看截图)却出现了一个”不知名符号“也没有结束程序,需要你重新输入ctrlz使程序结束,这又是怎么回事呢???

while ((ch = getchar()) != EOF)  让我们来看这一行代码,我们知道EOF是文件结束标志(End Of File)的意思,在windows系统中一般通过ctrl+z键来实现。那么这行语句的意思就是输入一个字符赋值给ch如果不等于EOF就执行循环。

实际上在c/c++中EOF并不是一个字符,它仅仅是一个宏定义,其值就是-1。当然了,getchar()函数的返回值也不是字符而是一个整型(读取成功时就返回该字符的ASCⅡ值,失败时就返回一个-1)

那么这行语句就变成了:当getchar()读取失败时返回-1赋值给ch,ch==EOF(-1)就终止循环,那么问题来了,怎样就算读取失败了呢??

实际上,^Z(ctrl+z)的ASCⅡ值是26,它是一个字符,只不过它含有一个流结束标志的作用

我们都知道,当我们输入一行字符按下回车就会将他们送到输入缓冲区中进行存储,系统此时会进行检测,看缓冲区中是否含有可读的数据或者ctrlz这样的结束标志。所以,当输入的^Z前面有其它可读的字符时,系统检测到前面的可读数据会认为该缓冲区中的数据可读,因此就会出现上面提到的”不知名符号“。也就是说,只有当你另起一行输入^Z按下回车,此时缓冲区中就只有这一个结束标志,此时系统便会认为读取失败,getchar()返回-1(也就是EOF),循环结束(亲爱的小伙伴们是不是恍然大悟了^-^)

让我们再来小小的扩充一下知识

在windows系统下ctrl+z为结束标志,在linux系统下ctrl+d为结束标志

当系统在检测缓冲区中是否含有流结束标志时,有两种检测方式:阻塞式和非阻塞式

阻塞式:指的是只有在回车键按下之后,才会对缓冲区中是否含有ctrl+z组合键进行检查。需要注意的是,当缓冲区中含有可读数据时,ctrl+z就不是结束标志了(上面已经说过了)。我们需要明白,ctrl+z产生的并不是一个普通的ASCⅡ码值,也就是说,它不会跟其他从键盘上输入的字符一样,它是不能够存放在输入缓冲区中的!!!

非阻塞时:指的是一旦按下ctrl+d之后立即响应。如果之前没有输入字符,那么ctrld就是流结束标志。如果之前已经输入了字符,那么ctrld此时就相当于回车不再是流结束标志,并且具有回车的功能(将输入字符送入缓冲区),并且这个回车自己也会进入缓冲区!!!

当然了windows系统一般采用阻塞式检查(ctrl+z),linux系统一般采用非阻塞式检查(ctrl+d)

你可能感兴趣的:(总结)