gpt4 book ai didi

c - freopen() 在缓冲方面的预期行为 (setvbuf())?

转载 作者:行者123 更新时间:2023-12-04 21:01:16 34 4
gpt4 key购买 nike

试图implement freopen() ,据我所知,我在标准中找到了一条实际上没有指定任何内容的规范。

所以... freopen()将关闭流(忽略错误),清除其错误和 EOF 标志,重置宽方向,然后以给定的模式重新打开流。这很清楚;这基本上是一个 fclose()/fopen()。即使它不是那样定义的,很明显这就是它的意图。

但是,我有两个关于事情的问题setvbuf()可以对流进行处理——设置用户分配的缓冲区,和/或更改缓冲区策略。

问题 1。

1) 是 freopen()期望将事情恢复到默认状态,就好像它实际上已经调用了 fopen() ?或者无论用户通过 setvbuf() 设置什么,它都有望转移到新的流中。就旧?这涉及缓冲存储器和缓冲策略,但这里的主要问题是缓冲存储器。
fclose()的规范指定用户通过 setvbuf() 与流关联的任何缓冲区已解除关联,即现在可以是 free()由用户。

但是freopen()仅指定它关闭与流关​​联的文件,而不是它 fclose()是的。

所以,在 freopen() 之后, 用户关联的缓冲内存是否仍然与流关联?

问题 2。
freopen()可以想象,可以在 FILE 上使用在调用时实际上并未与打开的文件关联的结构(因为尝试关闭文件的错误将被忽略)。

该文件结构可能是先前打开的流,具有用户分配的缓冲内存和缓冲策略。是 freopen()遵守这些设置,即将缓冲存储器/策略与“重新”打开的文件重新关联,或者是否将结构重新初始化为默认值,假设用户 free() d fclose()之后的缓冲存储器之前的文件?

我的。

看看第二季度,我没有看到标准库可以可靠地确定当前未打开的 FILE 的方法。具有用户分配的缓冲内存的结构仍然“拥有”该缓冲内存,或者用户是否已经回收了该内存。 (可以想象,该内存可能是本地的,即不属于 malloc()/free() 处理的内存列表的一部分,即使我愿意去那里——这将非常不寻常地涉及标准库函数所期望的工作。)

缓冲政策的类似考虑。

因此,据我所知,唯一可靠的处理方式是 freopen()将“与指定流关联的任何文件”的关闭处理为“真实”fclose() ,并将缓冲存储器/策略重新设置为默认值。

我的这种理解是对的,还是 Q1/Q2 有其他答案?

最佳答案

C 标准没有声明以任何方式修改缓冲状态。

整个C11 freopen() specification是(包括 footnote 272 ):

7.21.5.4 The freopen function

Synopsis

1

     #include <stdio.h>
FILE *freopen(const char * restrict filename,
const char * restrict mode,
FILE * restrict stream);

Description

2 The freopen function opens the file whose name is the string pointed to by filename and associates the stream pointed to by stream with it. The mode argument is used just as in the fopen function.272)

3 If filename is a null pointer, the freopen function attempts to change the mode of the stream to that specified by mode, as if the name of the file currently associated with the stream had been used. It is implementation-defined which changes of mode are permitted (if any), and under what circumstances.

4 The freopen function first attempts to close any file that is associated with the specified stream. Failure to close the file is ignored. The error and end-of-file indicators for the stream are cleared.

Returns

5 The freopen function returns a null pointer if the open operation fails. Otherwise, freopen returns the value of stream.


272) The primary use of the freopen function is to change the file associated with a standard text stream (stderr, stdin, or stdout), as those identifiers need not be modifiable lvalues to which the value returned by the fopen function may be assigned.



对我来说,关键短语是将流指向的流与它相关联。 stream 指向的预先存在的流有一个与之关联的新文件 - 仅此而已。通过不指定对缓冲的任何更改,这对我来说意味着保留当前的缓冲区状态,如 freopen()只是将新文件和模式与 相关联已有 溪流。只有对 FILE * 的那些更改通过我的阅读,应该制定标准中明确指出的流。

还要注意第 4 段: freopen函数首先尝试关闭与指定流关联的任何文件。同样,标准是指指定的流。

对我来说,结论似乎是不可避免的: freopen()不创建新流。它只是将预先存在的流指向一个新文件——这就是它所做的一切。

当前的实现支持这种读取——当前流的缓冲区状态未被修改。它们不会修改预先存在的流的缓冲状态。

GLIBC freopen() implementation也不是 the OpenSolaris/Illumos implementation (很可能是当前的 Solaris 实现)似乎修改了原始缓冲的状态,而不是在关闭文件之前刷新任何缓冲区。
freopen()功能似乎没有详细说明。 POSIX has this to say :

APPLICATION USAGE

The freopen() function is typically used to attach the pre-opened streams associated with stdin, stdout, and stderr to other files.

Since implementations are not required to support any stream mode changes when the pathname argument is NULL, portable applications cannot rely on the use of freopen() to change the stream mode, and use of this feature is discouraged. The feature was originally added to the ISO C standard in order to facilitate changing stdin and stdout to binary mode. Since a 'b' character in the mode has no effect on POSIX systems, this use of the feature is unnecessary in POSIX applications. However, even though the 'b' is ignored, a successful call to freopen (NULL, "wb", stdout) does have an effect. In particular, for regular files it truncates the file and sets the file-position indicator for the stream to the start of the file. It is possible that these side-effects are an unintended consequence of the way the feature is specified in the ISO/IEC 9899:1999 standard, but unless or until the ISO C standard is changed, applications which successfully call freopen (NULL, "wb", stdout) will behave in unexpected ways on conforming systems in situations such as:

{ appl file1; appl file2; } > file3

which will result in file3 containing only the output from the second invocation of appl.

关于c - freopen() 在缓冲方面的预期行为 (setvbuf())?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60113158/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com