2014-01-27 25 views
0

我正在嘗試用C打開一個文件的各種模式。我在r +,w +和a +模式下卡住了一點。fopen中r +模式的問題()

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

int main(void) 
{ 
    ..... 
    /* make a file with something in it */ 
    if((fp = fopen(filename, "w"))) 
    { 
     fprintf(fp, "abcd"); 
     fclose(fp); 
    } 
    /* see how r+ works */ 
    if((fp = fopen(filename, "r+"))) 
    { 
     int c = 0; 

     /* read something */ 
     c = fgetc(fp); 
     printf("c is %c\n", c); 

     /* write something */ 
     fseek(fp, -1, SEEK_CUR); 
     fputc('x', fp); 
     fflush(fp); 

     /* read something */ 
     c = fgetc(fp); 
     printf("c is %c\n", c); 

     /* rewind and show the whole thing */ 
     rewind(fp); 
     while((c = fgetc(fp)) != EOF) 
     { 
      printf("c is %c\n", c); 
     } 

     fclose(fp); 
    } 

    return 0; 
} 

這使我下面的輸出 -
c是
Ç爲b
c是X
Ç爲b
c是C
c是d

即使我在這裏刪除fflush() -

/* write something */ 
fseek(fp, -1, SEEK_CUR); 
fputc('x', fp); 
//fflush(fp); 

它給了我相同的輸出。那麼,如何在輸出流上不使用fflush()?(我是對fputc()寫在輸出流上?)另外,我可以在上面的代碼片段中使用fflush()而不是fseek()嗎?

回答

2

每C11 7.21.5.3.7:

當一個文件被打開與更新模式......輸出不得直接 後面輸入中間沒有調用fflush 函數或文件定位功能(fseek,fsetposrewind),輸入不應直接跟隨輸出,除非輸入 操作遇到文件結束,否則不輸入 中間調用文件定位功能。

,你得到未經您的通話fflush()相同的輸入不被標準保證的(雖然有些實現,包括glibc的,允許它,所以它並不奇怪,看看它在這裏工作)的事實。

對於你的其他問題,不,你不能在這裏使用fflush()而不是fseek(),因爲你的fseek()出現在輸出操作之前,而不是輸入操作。 fflush()僅對輸出流有意義,對於沒有輸入最近操作的更新流纔有意義。

+0

謝謝!這說明了很多。另外,我們編寫的任何東西(比如'fputc()')都會在輸出流中發生嗎? –

+0

你有正確的想法,但從技術上講,當你用'r +'打開時,你在這裏有一個更新流,而不是單獨的輸出和輸入流。像'fputc()'這樣的函數將輸出到更新流,像'fgetc()'這樣的函數將從更新流獲得輸入。 –

+0

再次感謝!很有幫助。 –