2014-02-14 47 views
1

我正在閱讀APUE並嘗試stdio.h中的內存流。不過,我對自動寫作機制感到非常困惑。'fseek()+ output'在C標準I/O庫存儲器流上行爲奇怪

這裏是APUE5.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); 
} 

"hello, world"的第一個輸出之後,flush()fseek()都會自動寫入。
的行爲是「你好,世界」的第二輸出後的不同,並呼籲FCLOSE():由'\0',這是我所期待的

當我使用flush()"hello, world"第二輸出如下:

初始緩衝內容:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
後fflush/FSEEK:你好,世界
後FCLOSE:您好,worldhello,world2

然而,當我切換到fseek(fp, 12, SEEK_SET),的"hello, world"第二輸出後面沒有一個 '\ 0' 任何更多:

初始緩衝內容:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
後fflush/FSEEK:你好,世界
FCLOSE後:您好,worldhello,world2aaaaaaaaaaaaaaaaaaaaa

這意味着內存流不會將第二輸出作爲increasing the amount of data

我做這個實驗的SUSE Linux企業服務器11(x86_64的)SP1

你有關於任何想法?或者它實際上是一個系統的錯誤?

提前感謝。

回答

0

[過長評論:]

空字節在流中的當前位置寫每當我們增加了流的緩衝區的數據量和FCLOSE打電話,fflush,FSEEK,fseeko或fsetpos

文檔的不同就從APUE以上報價:

Linux man-page說:

當已經打開用於寫入的流沖洗(fflush(3)) 或關閉(FCLOSE(3)),空字節是在 緩衝區的末尾寫入如果有空間。 [...]流的文件位置可以使用fseek(3)或fseeko(3)進行更改。將文件位置移動到已寫入數據的末尾,用零填充介入空間。

POSIX says

當打開時用於寫入的流被刷新或關閉時,空字節應在當前位置或在緩衝器的末端被寫入,這取決於內容的大小。

因此,POSIX不像Linux文檔那樣明確地重新編寫fseek*的操作。