2014-01-27 75 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

再次感谢!很有帮助。 –