繁体   English   中英

setvbuf 究竟是如何填充缓冲区的?

[英]How exactly does setvbuf fill the buffer?

为了更好地理解 setvbuf 的用法,我有一些问题:

我想将文件中的一行读入缓冲区,然后随意读取/解析它。 问题是,如何获得线路。 我的印象是_IOLBF逐行从 stream 读取 setvbuf。 从 C99 ISO 我了解到对 setvbuf 的调用只是将一个(或没有)缓冲区分配给 stream 但尚未对其进行操作。

所以我想如果我之后从 stream 读取它应该首先填充缓冲区然后从这个缓冲区执行操作(在这种情况下读取)。 那是对的吗? 如果不是:它究竟是如何工作的?

这是一个小例子。 我的期望是,一旦我调用 fread,缓冲区将被字符填充,直到\n或达到给定大小。 然后我想用 printf 从缓冲区中取出行(或字符数)。 除了需要“正确”大小的 arguments 之外,它几乎可以按照我的解释进行解释。

#include <stdio.h>

#define BUF_SIZE 64

int main()
{
    char buffer[BUF_SIZE];
    char buffer2[BUF_SIZE];
    FILE* fp;
    fp = fopen("file.dat", "r");
    setvbuf(fp, buffer, _IOLBF, 64);
    fread(buffer2, 1, 32, fp);
    printf("buffer:\n%s\n", buffer);
    printf("buffer2:\n%s\n", buffer2);
    fclose(fp);
    return 0;
}

让我烦恼的是我读了

当 stream 使用它进行缓冲时,您不应该尝试直接访问数组中的值。

如本链接所述: https://www.gnu.org/software/libc/manual/html_node/Controlling-Buffering.html

这是为什么?

最后我在这里读到: http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/016_c_ein_ausgabe_funktionen_020.htm (虽然这是德语,但我的问题中提供了理解这一点所需的一切。)

那行:

setvbuf(src, NULL, _IOLBF, 80);
setvbuf(dest, NULL, _IOLBF, 80);

将 80 个字符从 src 复制到 dest,我用我的文件 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 和 stdout 进行了测试,希望我能在终端上看到 output。 这没有用。 为什么?

您不能以任何有用的方式真正依赖它。 该规范以模糊、通用的方式描述了不同的缓冲模式,因为不同的环境和流类型对执行 I/O 的方式有限制。

在规范的文件部分它说:

当 stream 未缓冲时,字符应尽快从源或目标出现。 否则,字符可能会作为一个块被累积并传输到主机环境或从主机环境传输。 当 stream 被完全缓冲时,当缓冲区被填满时,字符将作为块传输到主机环境或从主机环境传输。 当 stream 被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输。 此外,当缓冲区被填满时,当在无缓冲的 stream 上请求输入时,或者当在需要从主机环境传输字符的缓冲 stream 上请求输入时,字符将作为块传输到主机环境. 对这些特性的支持是实现定义的,并且可能会受到 setbuf 和 setvbuf 函数的影响。

setvbuf本身的描述中,它说:

参数模式决定了 stream 将如何被缓冲,如下所示: _IOFBF 导致输入/输出被完全缓冲; _IOLBF 导致输入/输出被行缓冲; _IONBF 导致输入/输出无缓冲。 如果 buf 不是 null 指针,则可以使用它指向的数组而不是 setvbuf 函数分配的缓冲区273) 并且参数 size 指定数组的大小; 否则,size 可能决定由 setvbuf function 分配的缓冲区的大小。 数组的内容在任何时候都是不确定的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM