为什么在C语言中输入函数不能跟随输出函数,反之亦然?

时间:2019-01-07 01:10:25

标签: c io

我的课本说:

”“如果没有中间调用fflush,fseek,fsetpos或rewind,则输入函数不能跟随输出函数,反之亦然 通过采用在每次输入操作之前刷新缓冲区的规则,可以解决流I / O的第一个限制。但是,解决第二个限制的唯一方法是在同一打开的套接字描述符上打开两个流,一个用于读取,一个用于写入。”

所以我的问题是:

  1. 为什么输入函数不能跟随输出函数,反之亦然?
  2. 为什么第二个限制不能通过添加fflush操作来解决?

1 个答案:

答案 0 :(得分:3)

C标准说的话有点类似,您的书大概就是这样说的:

  

C11 ¶7.21.5.3 The fopen function

     

¶7当以更新模式打开文件时(上面的模式参数值列表中的第二个或第三个字符“ +”),输入和输出都可以在关联的流上执行。但是,在没有中间调用fflush函数或文件定位函数(fseekfsetposrewind)的情况下,在输出之后不能直接输入输入,并且除非输入操作遇到文件末尾,否则在没有中间调用文件定位功能的情况下,输入后不能直接跟随输出。在某些实现中,以更新模式打开(或创建)文本文件可能会打开(或创建)二进制流。

这些规则允许图书馆控制一切。它可能必须清除ungetc()推回的字符,或者安排刷新输出,以便可以合理地完成输入或执行其他操作。请注意,这些规则适用于文件流(FILE *)。通常,在使用套接字时,您使用文件描述符(int)而不是文件流,并且这些规则根本不适用。

请注意,fseek(fp, 0, SEEK_CUR)是一种定位操作,它可以保留输入位置(从当前偏移量开始寻找零字节),除了丢失ungetc()推回的字符之外。

与使用fflush()相比,使用fseek()是一种繁重的操作方式。

对于套接字,单个文件描述符用于读取和写入远程方。但是,由于文件描述符函数没有缓冲,因此对于已读取但尚未使用的数据该怎么做没有混淆(通过标准I / O流读取时很容易发生),也没有混淆如何处理已写入I / O缓冲区但尚未发送到远程的数据。此外,与磁盘文件不同,套接字不是可搜索的设备。管道,FIFO,终端和许多其他非磁盘,非磁带设备也都是不可检索的。但这并不能免除您遵循规则的麻烦,但是可更新的流通常用于磁盘等设备,您可以在其中读取所写的内容,而对于不可搜索的设备则不是这样。

因此,如果确实需要用于套接字I / O的文件流,则可能确实要使用两个单独的流,一个单独用于读取,另一个单独用于写入。在POSIX系统上,您可以使用dup()dup2()创建套接字文件描述符的副本,然后两次使用fdopen()创建读写流。