详解输入输出流结束标志ctrl+z和EOF

结论

windows下的ctrl+z用来作为结束输入输出流的标值,控制台读入字符^Z,只有另起一行放在行首才会起作用,否则表示结束本行,这对于java和C++都适用,注意一点,这里的结束输入输出不代表close()方法。

先来看一段代码

#include <stdio.h>
#include<windows.h>

#include<stdio.h>

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

}

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

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

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

实际上,^Z(ctrl+z)的ASCⅡ值是26,它是一个字符,只不过它含有一个流结束标志的作用在这里插入图片描述
当我们输入一行字符按下回车就会将他们送到输入缓冲区中进行存储,系统此时会进行检测,看缓冲区中是否含有可读的数据或者ctrlz这样的结束标志。所以,当输入的^Z前面有其它可读的字符时,系统检测到前面的可读数据会认为该缓冲区中的数据可读,因此就会出现上面提到的”不知名符号“。
简单的说就是如果^Z字符跟着普通的数据后面,它就被当成字符读入,存储为ascall码对应的字符;
如果是单独一个^Z系统就会识别出它是文件结束标识符,读的就是EOF,这个宏定义的字符。所以就返回-1了

补充

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

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

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

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

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

发布了79 篇原创文章 · 获赞 514 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/i6223671/article/details/89041492
今日推荐