Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么在更新模式下读写之间总是需要fseek或fflush?_C_File Io_Fseek - Fatal编程技术网

C 为什么在更新模式下读写之间总是需要fseek或fflush?

C 为什么在更新模式下读写之间总是需要fseek或fflush?,c,file-io,fseek,C,File Io,Fseek,问:我正在尝试更新中的一个文件 使用fopen模式“r+”,放置, 读某个字符串,然后写 返回一个修改过的字符串,但它不是 工作 答:一定要先打电话给fseek 你写,都是为了找回原处 您正在尝试的字符串的开头 因为fseek 或fflush在 读/写模式中的读和写 “+”模式。 我的问题是为什么在读/写“+”模式下读和写之间总是需要fseek或fflush?第5.2节 安德鲁·柯尼格的 (1989)提到这是因为向后兼容性问题。有人能详细解释一下吗?库缓冲输入和输出操作。查看该函数的setvbu

问:我正在尝试更新中的一个文件 使用
fopen
模式
“r+”
,放置, 读某个字符串,然后写 返回一个修改过的字符串,但它不是 工作

答:一定要先打电话给
fseek
你写,都是为了找回原处 您正在尝试的字符串的开头 因为
fseek
fflush
在 读/写模式中的读和写 “+”模式。

我的问题是为什么在读/写“+”模式下读和写之间总是需要
fseek
fflush
?第5.2节 安德鲁·柯尼格的 (1989)提到这是因为向后兼容性问题。有人能详细解释一下吗?

库缓冲输入和输出操作。查看该函数的
setvbuf()
\u IOFBF
\u IOLBF
参数

fseek()
fflush()
要求库提交缓冲操作


该标准规定必须执行搜索或刷新操作,以允许库使用某些快捷方式;否则,对于每个I/O操作,lib都必须检查前一个操作是否也是读操作(或写操作),如果I/O的“方向”发生变化,lib将自行触发刷新。在规范不变的情况下,库可能会假定客户端在更改I/O方向之前进行了查找/刷新。

,因为这样可以简化操作系统/库代码。文件流可能有单独的读写缓冲区,并且需要额外的努力来确保它们总是同步的。这会在不需要的时候降低性能

因此,程序员需要在需要时明确地执行此操作。

阅读Plauger的“”,了解(C89)标准库的各种功能为何如此,特别是标准I/O库的某些部分为何如此。一个原因是C运行在非常不同的系统和不同的媒体上;磁带等设备的处理方式可能与您习惯使用的磁盘驱动器有所不同。此外,在UNIX上,考虑你的“TTY”设备——它将键盘和鼠标连接到屏幕三——完全不同的硬件。协调两者之间的关系已经足够棘手了;标准中的规则使之更容易


请注意,标准规定了这一点。这来自C11标准ISO/IEC 9899:2011,但之前版本中的措辞类似:

^7以更新模式打开文件时(“+”作为文件中的第二个或第三个字符) 上述模式参数值列表),可在上执行输入和输出 关联流。但是,输出后不得直接跟随输入,无需 对
fflush
函数或文件定位函数(
fseek
)的中间调用,
fsetpos
,或
倒带
),输入后不得直接跟随输出,无需 对文件定位函数的中间调用,除非输入操作遇到文件结尾。使用更新模式打开(或创建)文本文件可能会打开(或创建)文本文件 一些实现中的二进制流


“c陷阱和陷阱”已经有20多年的历史了-你真的需要与20年前的旧东西向后兼容吗?即使这本书已经有20年的历史了,这些规则仍然有效。注意:c标准中关于这一要求的相关部分是C117.21.5.3/7@JonathanLeffler如果我打算写入现有文件的前半部分,然后立即读取剩余的旧数据,因为我需要在读写模式之间刷新,我是否需要使用
fseek(pFile,0,SEEK\u CUR)
确保缓冲区由于
fseek()
设置文件指针位置保持不变而刷新?我提出了一个问题,但没有得到答案@JonathanLeffler进一步说,参考文献中说,如果写入
读取操作未到达文件结尾,则需要刷新。间接地说,这是否意味着如果读取到达文件结尾,我们希望从该结尾写入,我们不需要刷新缓冲区?@Thokchom:4年后-很抱歉延迟:标准上说,如果您读取并遇到EOF,那么您可以立即写入而无需搜索操作。见我回答中的引语。