Programación General > C/C++

 Problema con fread()

(1/1)

granzeta:
Saludos al foro :)
haciendo mis practicas en C, he realizado un programa que Graba y lee una matriz de 25 enteros, la grabación con fwrite() es OK, pero al leer el archivo con fread() solo me recupera 12 de los 25 elementos grabados.

--- Código: C ---ret = fwrite(&matriz, object_size, object_count, flujo); //OK "ret" devuelve 25 ret = fread(&matriz, object_size, object_count, flujo); //FALLO "ret" devuelve 12  fread me devuelve el numero de objetos grabados (en "ret"); Este valor debe a su vez debe coincidir con object_count que es 25, igual que en fwrite.

matriz grabada --->   matriz leida
2   4   6   8  10 --->   2 4 6 8 10
12 14 16 18 20 --->   12 14 16 18 20
22 24 26 28 30 --->   22 24 0 0 0
32 34 36 38 40 --->   0 0 0 0 0
42 44 46 48 50 --->   0 0 0 0 0

Detalles Sistema
SO: Windows XP,  Compilador: gcc 4.5.2 (MinGW)

codigo completo

--- Código: C --- int fila, col;int matriz[5][5]={        2,4,6,8,10,        12,14,16,18,20,        22,24,26,28,30,        32,34,36,38,40,        42,44,46,48,50    };    int main(){     FILE *flujo;    int close_error;    char archivo[]="numbers.dat";     size_t object_size = sizeof(int);    size_t object_count = 25;    size_t ret;    /*Valores Iniciales*/    imprime_matriz();     flujo = fopen(archivo, "w");    ret = fwrite(&matriz, object_size, object_count, flujo);    printf("elementos grabados %dn", ret);    if (ret != object_count)            printf("Error al excribir datos al archivon");           close_error = fclose(flujo);       /*VACIAMOS LA MATRIZ A CEROS*/            for (fila = 0; fila <= 4; fila++){        for(col=0; col <= 4; col++){            matriz[fila][col]=0;                    }           }    /*LEEMOS EL ARCHIVO*/     flujo = fopen(archivo, "r");    ret = fread(&matriz, object_size, object_count, flujo);      printf("elementos retornados %dn", ret);    if (ret != object_count)        printf("Error leyendo data desde archivo...!n");           imprime_matriz(&matriz);        fclose(flujo);     return 0;} void imprime_matriz(){    for (fila =0; fila<=4 ; fila++){        for (col=0; col<=4; col++)            printf("%d ", matriz[fila][col]);        printf("n");    }}  

ProfesorX:
Encontre la fuente de tu problema.

Resulta que bajo windows hay 2 modos de abrir los archivos, en modo binario y en modo texto.

En modo texto la secuencia 0A en este caso se traduce erroneamente como el fin de una linea, entonces al leer/escribir divide el contenido en lineas, y por eso trunca el contenido. De hecho, el tamaño de tu archivo era de 101 bytes y no 100 bytes (25x4) como debia ser, ya que convertia el 0A en 0D 0A al escribir. En windows cada linea lleva un retorno de carro / avance de linea, en linux solo existe el avance de linea 0A, y todos los archivos se manejan como si fueran binarios.

Si no especificas el modo, los archivos se abren por defecto en modo texto.

La solucion es especificar explicitamente que vas a abrir el archivo en modo binario, de esa forma se elimina el problema.

Debes cambiar las siguientes lineas:


--- Código: C++ ---    flujo = fopen(archivo, "w"); 
por


--- Código: C++ ---    flujo = fopen(archivo, "wb"); y


--- Código: C++ ---    flujo = fopen(archivo, "r"); 
por


--- Código: C++ ---    flujo = fopen(archivo, "rb"); 

Saludos :)

granzeta:
Muchas gracias profesorX, su explicación y conclusión es detallada y exacta respectivamente.
Realmente esta genial su explicación  :good: de gran ayuda.
Asi que PROBLEMA SOLUCIONADO.
Saludos   :rolleyes:

Epa:
Aunque eso te soluciona el problema, sigue habiendo un error.

En tu caso no afecta por la forma en que defines la matriz.

pero esto


--- Código: C --- ret = fwrite(&matriz, object_size, object_count, flujo); //OK "ret" devuelve 25 ret = fread(&matriz, object_size, object_count, flujo); //FALLO "ret" devuelve 12   
deberia ser


--- Código: C --- ret = fwrite(matriz, object_size, object_count, flujo); //OK "ret" devuelve 25 ret = fread(matriz, object_size, object_count, flujo); //FALLO "ret" devuelve 12   
ya que si tu matriz es dinamica estarias escribiendo y lellendo de cualquier lado.

Saludos

granzeta:
Gracias, sus comentarios son de mucha ayuda cuando se esta aprendiendo a programar en C.

Navegación

[0] Índice de Mensajes

Ir a la versión completa