我知道这可能是个愚蠢的问题,但我不确定从终端获取用户输入的实际效果如何。
我从概念上理解输入/输出,使用它们也没有问题,但当涉及到这些在基本层面上的实际实现方式时,我就迷失了。
据我所知,所有流对象都使用一种缓冲区。如果你提取你到达eof的所有字符。这部分我可能是错的,我想了解更多。例如,当我们使用 std::cin 的提取器运算符时,它会等待输入。它如何区分等待输入和到达 eof(没有其他可读)?
最佳答案
std::cin
没有做任何特别的事情。像所有文件输入一样,它
发出系统级读取(read
在 Unix 中,ReadFile
在
Windows),以获得足够的字节来填充其缓冲区(通常是
今天超过 1K)。它是检测到的系统
输入来自键盘,并且表现不同:来自文件,
系统将读取尽可能多的可用字节,直到
文件末尾或请求的编号,并立即返回。
从键盘,系统将正常读取字符
进入内部缓冲区直到进入,以允许编辑(返回
空间等),并且只有在输入时才会将此缓冲区传回
调用者(在附加了新的行标记之后)。
编辑:
有点像对在
讨论:我将以 Unix 中发生的事情为例
系统(但 Windows 基本相同,取模方式
报告不同的信息)。 istream
本身是
缓冲的。当您尝试提取字符(>>>
运算符、istream::get
等),流将从
它的缓冲区。如果缓冲区中没有更多字符,
它将向系统发出一个read
请求,地址为
及其缓冲区的大小。 (在今天的系统上,我会
惊讶地看到不到 1K 的缓冲区。)什么系统
用它做什么将取决于文件描述符指定的内容:
- 一个文件
- 系统将从当前位置开始复制字节 文件,直到它填满缓冲区或到达文件末尾。它 返回它复制的字节数(或 -1,如果有 错误)。
- 键盘
- 对于键盘,系统维护一个内部缓冲区 它自己的,并逐行读取。这个缓冲区只会 当用户按下 enter 时被视为“准备就绪”;在此之前, 系统根本不会从 read 返回。这允许 执行行编辑的系统;例如处理类似的事情 退格键。当您按下回车键时,系统会添加(系统 特定的)新行序列到缓冲区,并返回 它已复制到缓冲区中的字符数。 (因此,不 0,因为有换行。)这个程序可以修改 两种方式:Unix 和 Windows 都有特殊字符 (Unix 下的 control-D,Windows 下的 control-Z)告诉 系统立即从读取返回,无论 缓冲区目前包含。如果你刚开始 一行,缓冲区不包含任何内容,`read` 返回 读取了 0 个字符,流将其视为文件结尾。 如果流缓冲区大小小于中的字符数 该行(因为你已经冷静地输入了 100000 个字符 没有新行),`read` 将返回将要返回的最大值 适合缓冲区,下一个 read 将立即返回 与该行的其余部分(或下一个 `read` 将返回 立即,直到读完整行)。
- 一个管道
- 系统会等到有足够多的 管道中请求的字符,或者没有更多 留下管道以供写入的进程。然后它会复制 请求的字符数(或更少,写入端 关闭),并返回复制的数字。
如果read
指示错误,流将设置badbit
;
如果 read
返回 0 个字符读取,流将处理
它作为文件的结尾。
关于c++ - 为什么 std::cin 的提取器操作符等待用户输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23892889/