Jam*_*nze
8
std::cin没有什么特别的.像所有文件输入一样,它会发出一个系统级读取(read在Unix中,ReadFile在Windows中),以获得足够的字节来填充其缓冲区(通常今天超过1K).它是检测输入来自键盘的系统,行为不同:从文件中,系统将读取尽可能多的字节,直到文件末尾或请求的数字,并立即返回.从键盘,系统通常会将字符读入内部缓冲区,直到进入,允许编辑(后退空间等),并且只有在输入时才会将此缓冲区传递回调用者(在添加新行标记之后) ).
编辑:
作为讨论中提到的元素的摘要排序:我将以Unix系统中的情况为例(但Windows基本相同,以报告不同信息的方式为模).它istream本身是缓冲的.当您尝试提取字符(>>
运算符istream::get等)时,流将从其缓冲区返回它.如果缓冲区中没有剩余字符,它将read向系统发出请求,其地址和缓冲区大小.(在今天的系统中,我会惊讶地看到一个小于1K的缓冲区.)系统用它做什么将取决于文件描述符指定的内容:
- 一份文件
- 系统将从文件中的当前位置复制字节,直到它填满缓冲区或到达文件末尾.它返回它复制的字节数(如果有错误,则返回-1).
- 键盘
- 对于键盘,系统维护自己的内部缓冲区,并逐行读取.当用户按下回车键时,此缓冲区仅被视为"就绪"; 在此之前,系统将不会从`read`返回.这允许系统实现行编辑; 例如处理退格之类的东西.当您按Enter键时,系统会将(系统特定的)新行序列添加到缓冲区,并返回其已复制到缓冲区中的字符数.(因此,不是0,因为有新行.)此过程可以通过两种方式进行修改:Unix和Windows都有一个特殊字符(Unix下的control-D,Windows下的control-Z),它告诉系统返回立即从读取,当前缓冲区包含的内容.如果你在一行的开头,缓冲区什么都没有,`read`返回0个字符读取,并且流将它视为文件的结尾.如果流缓冲区大小小于行中的字符数(因为你在没有新行的情况下平静地键入了100000个字符),`read`将返回适合缓冲区的最大值,并且下一个` read`将立即返回该行的其余部分(或者下一个n`read`将立即返回,直到读取整行).
- 管道
- 系统将等待,直到管道中请求的字符数量尽可能多,或者管道打开以进行写入时不再有剩余的进程.然后它将复制请求的字符数(或更少,写入侧关闭),并返回复制的数字.
如果read指示错误,则流将设置badbit; 如果read返回0个字符读取,则流将其视为文件末尾.