Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] ¿desplazamiento del apuntador de posición de archivo?

Estas en el tema de ¿desplazamiento del apuntador de posición de archivo? en el foro de C/C++ en Foros del Web. Lenguaje C Tengo una duda respecto a esto, estuve haciendo un programa para ordenar registros en un archivo de texto de acceso secuencial, y pues ...
  #1 (permalink)  
Antiguo 16/06/2016, 17:05
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 2 meses
Puntos: 0
¿desplazamiento del apuntador de posición de archivo?

Lenguaje C
Tengo una duda respecto a esto, estuve haciendo un programa para ordenar registros en un archivo de texto de acceso secuencial, y pues para eso tenía que leer y escribir registros constantemente, pero tenía problemas en la lectura del archivo, ya que a veces leía 2 veces el mismo registro.

si pongo varias instrucciones fprintf, los registros se almacenan de forma correcta, igual si pongo varias instrucciones fscanf se leen bien, eso me dice que el apuntador de posición de archivo se desplaza correctamente, pero si hago algo como lo siguiente:

Código C:
Ver original
  1. if((ptr = (fopen("texto2.txt","w+"))) != NULL){ ///abre un archivo de texto para lectura y escritura
  2.        fprintf(ptr, "%d %s %s %.2f\n", 23, "sg", "yf", 2.9); ///escribe el primer registro en el archivo
  3.    
  4.        
  5.        rewind(ptr); ///rebobina
  6.        fscanf(ptr, "%d%s%s%lf", &a, b, c, &e); ///lee el registro ingresado previamente
  7.        printf("%d %s %s %.2f\n", a, b, c, e); ///y lo imprime
  8.        
  9.        printf("\n\n");
  10.       fprintf(ptr, "%d %s %s %.2f\n", 24, "hol", "utr", 3.7); //escribe otro registro
  11.    
  12.  
  13.       rewind(ptr);
  14.       fscanf(ptr, "%d%s%s%lf", &a, b, c, &e); //lee e imprime
  15.       printf("%d %s %s %.2f\n", a, b, c, e); //los
  16.       fscanf(ptr, "%d%s%s%lf", &a, b, c, &e); //2 registros
  17.       printf("%d %s %s %.2f\n", a, b, c, e);  //que tiene el archivo
  18.      
  19.     }
El problema aquí es que el segundo registro no lo lee, y pues supuse que al momento de hacer la primera lectura, el apuntador de posición se desplazaria a la siguiente posición para almacenar el siguiente registro.
Pero por lo menos pienso yo que debería de sobreescribir entonces al primer registro.
Mi pregunta es esa, ya he hallado la forma de guardar los 2 registros, pero en el programa anterior nose que pasa con el segundo registro, ¿porque no se ejecuta y reemplaza al registro anterior?
Gracias...
  #2 (permalink)  
Antiguo 17/06/2016, 02:13
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: ¿desplazamiento del apuntador de posición de archivo?

No utilizas el mismo formato para leer y escribir y ello provoca que el puntero interno del fichero no apunte siempre donde tu crees:

Código C:
Ver original
  1. fprintf(ptr, "%d %s %s %.2f\n", 23, "sg", "yf", 2.9); ///escribe el primer registro en el archivo
  2.    
  3. long pos1 = ftell(ptr);
  4.        
  5. rewind(ptr); ///rebobina
  6. fscanf(ptr, "%d%s%s%lf", &a, b, c, &e); ///lee el registro ingresado previamente
  7. printf("%d %s %s %.2f\n", a, b, c, e); ///y lo imprime
  8.  
  9. long pos2 = ftell(ptr);
  10.  
  11. printf("posicion 1: %ld\n", pos1);
  12. printf("posicion 2: %ld\n", pos2);

Código:
23 sg 33@X 0.00
posicion 1: 15
posicion 2: 13


23 sg yf 2.90
23 sg yf 2.90
Y eso hace que los registros no se guarden exactamente donde tu pretendes. Fíjate que después de la lectura el puntero está retrasado dos bytes (en mi caso) que coincide justamente con el salto de línea. Lo que sucede después es que el segundo registro se almacena desalineado. Finalmente rebobinas e intentas leer dos registros... pero el segundo no se llega a leer porque antes de completar la lectura llegas al final del fichero... como no ha podido completar la lectura del segundo registro no te actualiza las variables y lo que acabas imprimiendo es el mismo registro dos veces (chequea el flag EOF si no te fias).

Yo he probado a homogeneizar la lectura y la escritura y me funciona correctamente:

Código C:
Ver original
  1. #define FORMAT1 "%d %s %s %.2f\n"
  2. #define FORMAT2 "%d %s %s %f\n"
  3. #define WRITE(fich,a,b,c,d) fprintf(ptr,FORMAT1,a,b,c,d)
  4. #define READ(fich,a,b,c,d)  fscanf(ptr,FORMAT2,a,b,c,d)
  5. #define PRINT(a,b,c,d)      printf(FORMAT1,a,b,c,d)
  6.  
  7. int main()
  8. {
  9.   int a;
  10.   char b[10],c[10];
  11.   float e;
  12.  
  13.   FILE* ptr;
  14.   if((ptr = (fopen("texto2.txt","w+"))) != NULL){ ///abre un archivo de texto para lectura y escritura
  15.     WRITE(ptr,23,"sg","yf",2.9);
  16.  
  17.     rewind(ptr); ///rebobina
  18.     READ(ptr,&a,b,c,&e);
  19.     PRINT(a,b,c,e);
  20.  
  21.     printf("\n\n");
  22.  
  23.     WRITE(ptr,24,"hol","utr",3.7); //escribe otro registro
  24.  
  25.  
  26.     rewind(ptr);
  27.     READ(ptr,&a,b,c,&e); //lee e imprime
  28.     PRINT(a,b,c,e); //los
  29.     READ(ptr,&a,b,c,&e); //2 registros
  30.     PRINT(a,b,c,e);  //que tiene el archivo
  31.  
  32.   }
  33. }

Resultado:

Código:
23 sg yf 2.90


23 sg yf 2.90
24 hol utr 3.70
Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Etiquetas: programa
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:10.