我正在阅读UNIX环境中的高级编程,第3版并且误解了其中的一个部分(第145页,第5.4节"缓冲",第5章).
线缓冲有两个警告.首先,标准I/O库用于收集每一行的缓冲区大小是固定的,因此如果我们在写入换行符之前填充此缓冲区,则可能发生I/O. 其次,无论何时通过标准I/O库从(a)无缓冲流或(b)行缓冲流(需要从内核请求数据)请求输入,所有行缓冲输出流都被刷新.(b)上的限定符的原因是所请求的数据可能已经在缓冲区中,这不需要从内核读取数据.显然,来自无缓冲流(项目(a))的任何输入都需要从内核获取数据.
我无法得到大胆的线条.我的英语不好.那么,你能为我澄清一下吗?也许以一种更简单的方式.谢谢.
描述的阴谋背后的关键是确保在系统进入等待输入的模式之前出现提示.
如果输入流是无缓冲的,则每次标准I/O库需要数据时,它必须转到内核以获取某些信息.(那是最后一句.)那是因为标准I/O库没有缓冲任何数据,因此当需要更多数据时,它必须从内核读取.(我认为即使是无缓冲的流也可能缓冲一个数据字符,因为它需要读取空格字符,例如,检测它何时到达%s格式字符串的末尾;它必须放回(ungetc())它读取的额外字符,以便下次需要一个字符时,会有它所放回的字符.但它永远不需要超过缓冲的一个字符.)
如果输入流是行缓冲的,则其输入缓冲区中可能已经存在一些数据,在这种情况下,可能不需要去内核获取更多数据.在这种情况下,它可能不会冲洗任何东西.如果scanf()请求的格式"%s"和您输入的格式,则会发生这种情况hello world; 它会读取整行,但第一次扫描会在之后停止hello,而下一次扫描scanf()不需要转到内核,world因为它已经在缓冲区中.
但是,如果缓冲区中没有任何数据,则必须要求内核读取数据,并确保刷新任何行缓冲的输出流,以便在写入时:
printf("Enter name: ");
if (scanf("%63s", name) != 1)
…handle error or EOF…
Run Code Online (Sandbox Code Playgroud)
然后Enter name:出现提示符().但是,如果您以前键入过hello world,之前只读过hello,那么提示不一定会出现,因为world已经在(行缓冲)输入流中等待.