• Sábado 4 de Mayo de 2024, 23:45

Autor Tema:  Problema con fread()  (Leído 2300 veces)

granzeta

  • Nuevo Miembro
  • *
  • Mensajes: 3
    • Ver Perfil
Problema con fread()
« en: Miércoles 22 de Junio de 2011, 01:14 »
0
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
  1. ret = fwrite(&matriz, object_size, object_count, flujo); //OK "ret" devuelve 25
  2.  
  3. ret = fread(&matriz, object_size, object_count, flujo); //FALLO "ret" devuelve 12 
  4.  
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
  1.  int fila, col;
  2. int matriz[5][5]={
  3.         2,4,6,8,10,
  4.         12,14,16,18,20,
  5.         22,24,26,28,30,
  6.         32,34,36,38,40,
  7.         42,44,46,48,50
  8.     };
  9.    
  10. int main(){ 
  11.     FILE *flujo;
  12.     int close_error;
  13.     char archivo[]="numbers.dat";
  14.  
  15.     size_t object_size = sizeof(int);
  16.     size_t object_count = 25;
  17.     size_t ret;
  18.     /*Valores Iniciales*/
  19.     imprime_matriz();
  20.  
  21.     flujo = fopen(archivo, "w");
  22.     ret = fwrite(&matriz, object_size, object_count, flujo);
  23.     printf("elementos grabados %dn", ret);
  24.     if (ret != object_count)   
  25.         printf("Error al excribir datos al archivon");      
  26.     close_error = fclose(flujo);     
  27.   /*VACIAMOS LA MATRIZ A CEROS*/       
  28.     for (fila = 0; fila <= 4; fila++){
  29.         for(col=0; col <= 4; col++){
  30.             matriz[fila][col]=0;           
  31.         }      
  32.     }  
  33.   /*LEEMOS EL ARCHIVO*/ 
  34.     flujo = fopen(archivo, "r");
  35.     ret = fread(&matriz, object_size, object_count, flujo);  
  36.     printf("elementos retornados %dn", ret);
  37.     if (ret != object_count)
  38.         printf("Error leyendo data desde archivo...!n");   
  39.    
  40.     imprime_matriz(&matriz);   
  41.     fclose(flujo);
  42.  
  43.     return 0;
  44. }
  45.  
  46. void imprime_matriz(){
  47.     for (fila =0; fila<=4 ; fila++){
  48.         for (col=0; col<=4; col++)
  49.             printf("%d ", matriz[fila][col]);
  50.         printf("n");
  51.     }
  52. } 
  53.  

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Problema con fread()
« Respuesta #1 en: Miércoles 22 de Junio de 2011, 03:27 »
0
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++
  1.     flujo = fopen(archivo, "w");
  2.  

por

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

Código: C++
  1.     flujo = fopen(archivo, "r");
  2.  

por

Código: C++
  1.     flujo = fopen(archivo, "rb");
  2.  


Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

granzeta

  • Nuevo Miembro
  • *
  • Mensajes: 3
    • Ver Perfil
Re: Problema con fread()
« Respuesta #2 en: Miércoles 22 de Junio de 2011, 04:15 »
0
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

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema con fread()
« Respuesta #3 en: Jueves 23 de Junio de 2011, 22:22 »
0
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
  1.  
  2. ret = fwrite(&matriz, object_size, object_count, flujo); //OK "ret" devuelve 25
  3.  
  4. ret = fread(&matriz, object_size, object_count, flujo); //FALLO "ret" devuelve 12
  5.  
  6.  

deberia ser

Código: C
  1.  
  2. ret = fwrite(matriz, object_size, object_count, flujo); //OK "ret" devuelve 25
  3.  
  4. ret = fread(matriz, object_size, object_count, flujo); //FALLO "ret" devuelve 12
  5.  
  6.  

ya que si tu matriz es dinamica estarias escribiendo y lellendo de cualquier lado.

Saludos
The sweet smell of a great sorrow lies over the land.


granzeta

  • Nuevo Miembro
  • *
  • Mensajes: 3
    • Ver Perfil
Re: Problema con fread()
« Respuesta #4 en: Sábado 25 de Junio de 2011, 00:43 »
0
Gracias, sus comentarios son de mucha ayuda cuando se esta aprendiendo a programar en C.