'fseek()+ output'在C标准I / O库内存流上表现奇怪

时间:2014-02-14 07:06:03

标签: c memorystream stdio fseek

我正在阅读APUE并在stdio.h中尝试内存流。但是,我对自动编写\0的机制感到非常困惑。

以下是APUE 5.14 Memory Streams上所说的内容:

  

每当我们增加流缓冲区中的数据量并调用fclose,fflush,fseek,fseeko或fsetpos

时,就会在流中的当前位置写入空字节

我使用以下代码进行了一些实验,以测试Increase the amount of data in the stream's buffer

的含义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BSZ 48

int main(){
    FILE *fp;
    char buf[BSZ];

    memset(buf, 'a', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';
    printf("Initial buffer content: %s\n", buf);

    if ((fp = fmemopen(buf, BSZ, "w+")) == NULL){
        fputs("fmemopen failed\n", stderr);
        exit(-1);
    }
    fprintf(fp, "hello, world");

    /* Confused Point Here !!! */
    fflush(fp);                   //works as expected
    //fseek(fp, 12, SEEK_SET);    //strange behavior

    printf("after fflush/fseek: %s\n", buf);

    fprintf(fp, "hello, world2");
    fclose(fp);
    printf("after fclose: %s\n", buf);

    exit(0);
}

flush()的第一个输出后,fseek()'\0'都会自动写入"hello, world"
在'hello,world'的第二个输出之后,行为是不同的,并调用fclose():

当我使用flush()时,"hello, world"的第二个输出后跟'\0',这是我的预期:

  

初始缓冲内容:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa   在fflush / fseek之后:你好,世界
  在fclose之后:你好,worldhello,world2

但是,当我切换到fseek(fp, 12, SEEK_SET)时,"hello, world"的第二个输出后面不再是'\ 0':

  

初始缓冲内容:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa   在fflush / fseek之后:你好,世界
  fclose之后:hello,worldhello,world2aaaaaaaaaaaaaaaaaaaaa

这意味着内存流不会将第二个输出视为increasing the amount of data

我在SUSE Linux Enterprise Server 11(x86_64)SP1上进行了此实验

你有什么想法吗?或者它实际上是系统的错误?

非常感谢。

1 个答案:

答案 0 :(得分:0)

[评论太长了:]

  

每当我们增加流缓冲区中的数据量并调用fclose,fflush,fseek,fseeko或fsetpos

时,就会在流中的当前位置写入空字节

文档与 APUE 的上述引用不同:

Linux man-page说:

  

刷新已打开以进行写入的流时(fflush(3))          或者关闭(fclose(3)),在结尾处写入一个空字节          缓冲区,如果有空间。 [...]可以使用fseek(3)或fseeko(3)更改流的文件位置。将文件位置移动到已经写入的数据的末尾,用零填充中间空间。

POSIX says

  

当一个打开写入的流被刷新或关闭时,应在当前位置或缓冲区末尾写入一个空字节,具体取决于内容的大小。

因此,POSIX并不像Linux文档那样具有解释性,而是在fseek*上重新做什么。

相关问题