gpt4 book ai didi

c - 在使用 fmemopen 打开的 FILE* 上使用 rewind()

转载 作者:太空宇宙 更新时间:2023-11-04 02:34:56 28 4
gpt4 key购买 nike

已通过 glibc 2.24 解决 -- 请参阅下面的更新

这是一段 C 代码(使用 gcc 5.3.1、glibc 2.23 编译):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

int main() {
const char* s1="Original content of file.\n"
"still original content and some remaining original content.\n";
const char* s2="overwriting data with new content\n";
const char* s3="appended data\n";

const size_t bufsz=strlen(s1)+1;
char buf[bufsz];
FILE *f;
int r;

f=fmemopen(buf,bufsz,"w");
assert(f!=NULL);

// setbuf(f, NULL); // variant no. 1
// setbuffer(f, buf, bufsz); // variant no. 2

r=fwrite(s1,strlen(s1),1,f);
assert(r==1);

r=fflush(f);
assert(r==0);

rewind(f);

r=fwrite(s2,strlen(s2),1,f);
assert(r==1);

r=fwrite(s3,strlen(s3),1,f);
assert(r==1);

r=fclose(f);
assert(r==0);

printf("%s",buf);
}
  • 它如我所料 -- 输出是:

    overwriting data  with new content
    appended data
    and some remaining original content.
  • 现在,联机帮助页 fmemopen(3) 建议要么禁用缓冲(取消注释变体 1),要么明确地将 buf 设置为缓冲区(取消注释变体 2)。

    然而,在这两种情况下,我得到的结果是:

    appended data
    ta with new content
    ginal content and some remaining original content.

    因此,附加数据并没有像预期的那样写入第二个内容,而是覆盖了第二个内容。

  • 如果我以二进制模式打开文件(即用“wb”替换“w”模式),行为保持不变。

  • valgrind 不报告任何错误(除了缓冲情况下的误报“源和目标重叠”。后一个是由于尝试将 STDIO 缓冲区写入内存,这确实是同一个地址。)

怎么了?我做错了吗?或者这是一个 GLIBC 错误?

更新

8 月 4 日,发布了新的 glibc 2.24 版本。使用 gcc 5.4.0 和 glibc 2.24,变体号。 1(无缓冲文件)工作正常。变体 2(自缓冲版本)给出了不同但仍然错误的结果。因此,我相信 R.. 声称这是联机帮助页 fmemopen(3) 中的文档错误是正确的。我会提出错误报告 ...

最佳答案

Now, the manpage fmemopen(3) advices to either disable buffering (uncomment variant 1), or to explicitely set buf as buffer (uncomment variant 2).

后者肯定是未定义的行为。不要这样做。我不清楚您在 Linux 手册页中找到的文本是什么:

Alternatively, the caller can explicitly set buf as the stdio stream buffer, at the same time informing stdio of the buffer's size, using:

setbuffer(stream, buf, size);

试图表达,但它是一个文档错误,可能应该被删除。

至于非缓冲模式不工作,这可能是一个 glibc 错误。尽量使测试用例尽可能小,针对最近的 glibc 进行测试,如果仍然发生,请在 glibc bugzilla 上提交错误报告:

https://sourceware.org/bugzilla/enter_bug.cgi?product=glibc

当您想立即了解错误时,一个安全的替代方法是调用 fflush 并检查返回值。

关于c - 在使用 fmemopen 打开的 FILE* 上使用 rewind(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38854163/

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