2010-02-09 663 views
10

¿Por qué el código siguiente no funciona? Quiero decir, muestra todo tipo de personajes extraños en la salida de la consola.¿Por qué necesito enjuagar mi flujo de E/S para obtener el resultado correcto?

#include <stdio.h> 
char mybuffer[80]; 
int main() 
{ 
    FILE * pFile; 
    pFile = fopen ("example.txt","r+"); 
    if (pFile == NULL) perror ("Error opening file"); 

    else { 
     fputs ("test",pFile); 

     fgets (mybuffer,80,pFile); 
     puts (mybuffer); 
     fclose (pFile); 
     return 0; 
    } 
} 

Sin embargo, el siguiente código funciona bien.

#include <stdio.h> 
char mybuffer[80]; 
int main() 
{ 
    FILE * pFile; 
    pFile = fopen ("example.txt","r+"); 
    if (pFile == NULL) perror ("Error opening file"); 

    else { 
     fputs ("test",pFile); 
     fflush (pFile);  
     fgets (mybuffer,80,pFile); 
     puts (mybuffer); 
     fclose (pFile); 
     return 0; 
    } 
} 

¿Por qué necesito enjuagar la corriente para obtener el resultado correcto?

Respuesta

12

Debido a que la norma así lo indique (§7.19.5.3/5):

Cuando se abre un archivo con el modo de actualización ('+' como el segundo o tercer carácter en la lista anterior del argumento de modo valores), tanto la entrada como la salida pueden ser realizadas en la secuencia asociada. Sin embargo, la salida no será directamente seguido de entrada sin un intervenir llamada a la función fflush o a un función de archivo de posicionamiento (fseek, fsetpos, o rebobinado), y de entrada no será directamente seguido de salida sin una llamada de intervención a una función de posicionamiento de archivo , a menos que la operación de entrada se encuentre con el fin de archivo.

Existe una razón para esto: la salida y la entrada normalmente se almacenan en el búfer por separado. Cuando hay una descarga o búsqueda, sincroniza los almacenamientos intermedios con el archivo, pero de lo contrario puede dejarlos fuera de sincronización. Esto generalmente mejora el rendimiento (por ejemplo, cuando haces una lectura, no tiene que verificar si la posición desde la que estás leyendo se ha escrito desde que se leyeron los datos en el búfer).

+0

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Mucho !!!!!! – Jaebum

+0

¿Pero por qué la salida de la segunda fuente no es "prueba"? Simplemente no muestra nada .. – Jaebum

+1

@Lee: Simple, lo leyó desde el punto en que dejó de escribir, necesita volver al principio para que funcione. – falstro

2

es porque el archivo C io funciona con un búfer. Esto solo se escribe en el disco cuando lo descarga, escribe un caracter/n o llena el búfer.

Por lo tanto, en el primer caso, su archivo no contiene nada cuando usted lee de él.

+0

Pero todavía no funciona, incluso si utilizo "prueba \ n" en lugar de "prueba". – Jaebum

+0

La respuesta es incorrecta a este respecto: escribir '\ n' en el archivo no tiene ningún efecto; debe vaciar el archivo o escribir tantos datos que la biblioteca C se vaciará sola (generalmente 4KiB). –

+0

Creo que el \ n bit depende de la implementación, MS lo hace, al menos para el código C++. – gbjbaanb

7

Al usar un archivo con un modo de lectura/escritura, debe llamar a fseek/fflush antes de diferentes operaciones de E/S.

Ver esta respuesta en why fseek or fflush is always required...

+0

Thx; Debería haber buscado más duro – Jaebum

Cuestiones relacionadas