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

Mostrar los últimos 5 registros de un archivo [C]

Estas en el tema de Mostrar los últimos 5 registros de un archivo [C] en el foro de C/C++ en Foros del Web. Hola a todos. El programa funciona como lo deseaba sólo que me carcome una duda, lareto sugirió leer y escribir en un archivo de la ...
  #1 (permalink)  
Antiguo 08/04/2015, 12:25
rdv316
Invitado
 
Mensajes: n/a
Puntos:
Mostrar los últimos 5 registros de un archivo [C]

Hola a todos.
El programa funciona como lo deseaba sólo que me carcome una duda, lareto sugirió leer y escribir en un archivo de la misma manera que yo utilizo en la lectura de este programa.-

Código:
#include <stdio.h>

typedef struct{
    char marcado;
	char ingles[30];
	char espaniol[30];
}Traductor;


int main(void){
	Traductor traductor;
	FILE *ptrFile;
	long cRegistros, l5u;
	
	if( ( ptrFile = fopen( "archivo.txt", "r" ) ) == NULL){
		perror("\n\n error..:");
		return 1;
	}

	fseek(ptrFile, 0, SEEK_END);
	cRegistros = ftell( ptrFile ) / sizeof( traductor );	
	
	for( l5u = cRegistros - 5 ; l5u < cRegistros; l5u++ ){
		fseek( ptrFile, l5u*sizeof(traductor), SEEK_SET );

		fread( &traductor.marcado, sizeof(char), 1, ptrFile );
		fread( &traductor.ingles, sizeof(char), 30, ptrFile );
		fread( &traductor.espaniol, sizeof(char), 30, ptrFile );

		printf( "\n\n %-10s ->  %-15s", traductor.ingles, traductor.espaniol);
	}
		
	printf( "\n\n Pulse [Enter] para finalizar..." ); getchar();
	return 0;
}
Código:
cRegistros = ftell( ptrFile ) / sizeof( traductor );
en este caso sizeof( traductor ) puede fallar en el conteo de los registros y si no es correcta esta sintaxis ¿cómo debería contar los bytes que tiene la estructura?.-


Saludos y un abrazo.
Daniel
  #2 (permalink)  
Antiguo 08/04/2015, 15:49
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Se hace tal como lo tienes en la estructura. Tras mover el cursor al final del archivo haces: cRegistros = ftell( ptrFile ) / ( sizeof(char) + (sizeof(char)*30) + (sizeof(char)*30) );

Que también puede ser: cRegistros = ftell( ptrFile ) / ( sizeof(char) + sizeof(Traductor.ingles) + sizeof(Traductor.espaniol) );

Lo que debes evitar es tomar el tamaño de la estructura con el sizeof, ya que te tragas la alineación de bytes que te puede inflar la estructura dependiendo del compilador que uses y una serie de reglas no vienen al caso, pero nada te impide hacer la suma de cada dato por separado para obtener el tamaño real de la estructura. =)

un ejemplo es:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <windows.h>
  4.  
  5. struct Datos{
  6.     int edad;
  7.     char nombre[20];
  8.     double peso;
  9. };
  10.  
  11. void escribe_traductor ( FILE *fp, struct Datos *dato );
  12. void lee_traductor ( FILE *fp, struct Datos *dato );
  13.  
  14. int main () {
  15.     FILE *ptrFile;
  16.     ptrFile = fopen ( "archivo.txt", "w+" );
  17.     int i;
  18.     long cRegistros, l5u;
  19.    
  20.     if ( ptrFile == NULL ) {
  21.         printf ( "No ha sido crear abrir archivo.txt" );
  22.         return 1;
  23.     }
  24.    
  25.     //Creamos algunos datos para escribir en el fichero
  26.     struct Datos dato[5] = {
  27.         { 24, "Rafael", 82.25 },
  28.         { 0, "José", 76.07 },
  29.         { 969, "Matusalén", 75.70},
  30.         { 28, "Manola", 140 },
  31.         { 42, "Obama", 70 }
  32.     };
  33.    
  34.     escribe_traductor( ptrFile, &dato[2] ); // escribimos uno de los registros, el 3º registo lo escribiremos.
  35.  
  36.     //al escribir ya estamos al final del fichero, no hace falta fseek(ptrFile, 0, SEEK_END);
  37.     cRegistros = ftell( ptrFile ) / ( sizeof( int ) + ( sizeof( char ) * 20 ) + sizeof ( double ) );
  38.     printf("actualmente hay %ld registro/s en el archivo\n", cRegistros);
  39.    
  40.     //probamos poner más 2 registro a ver
  41.     escribe_traductor( ptrFile, &dato[0] );
  42.     escribe_traductor( ptrFile, &dato[3] );
  43.    
  44.     //aun estamos al final, no usamos fseek por que no hace falta ;)
  45.     cRegistros = ftell( ptrFile ) / ( sizeof( int ) + ( sizeof( char ) * 20 ) + sizeof ( double ) );
  46.     printf("actualmente hay %ld registro/s en el archivo\n", cRegistros);    
  47.    
  48.     fclose ( ptrFile );
  49.     getchar();
  50.     return  0;
  51. }
  52.  
  53. void escribe_traductor ( FILE *fp, struct Datos *dato ) {
  54.     fwrite ( &dato->edad, sizeof ( int ), 1, fp );
  55.     fwrite ( dato->nombre, sizeof ( char ), 20, fp );
  56.     fwrite ( &dato->peso, sizeof ( double ), 1, fp );
  57.    
  58. }
  59.  
  60. void lee_traductor ( FILE *fp, struct Datos *dato ) {
  61.     fread ( &dato->edad, sizeof ( int ), 1, fp );
  62.     fread ( dato->nombre, sizeof ( char ), 20, fp );
  63.     fread ( &dato->peso, sizeof ( double ), 1, fp );
  64. }
  #3 (permalink)  
Antiguo 08/04/2015, 18:55
rdv316
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Hola vangodp.
Gracias por tú tiempo, ya no me quedan dudas y me vino muy bien que me refrescaras lo de array de estructura.-

Daniel
  #4 (permalink)  
Antiguo 08/04/2015, 19:17
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

De nada ;) Aprendemos juntos.

Lo de array de estructuras es solo para no tener que estar llenando a mano esos datos, así nos centramos en lo que realmente nos interesa que es leer y escribir en el fichero.
  #5 (permalink)  
Antiguo 09/04/2015, 19:54
rdv316
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Hola.

Código:
.............................
typedef struct{
     char b;
     char fecha[11];
     float verduras;
     float almacen;
     char nota[101];
}Super;
.............................
Código:
.............................
     fread(&super->b, sizeof(char), 1, ptrFile);	
     fread(&super->fecha, sizeof(char), 11, ptrFile);	
     fread(&super->verduras, sizeof(float), 1, ptrFile);	
     fread(&super->almacen, sizeof(float), 1, ptrFile);	
     fread(&super->nota, sizeof(char), 101, ptrFile);
.............................
Código:
.............................
     int tamStructSuper = sizeof(char) + (sizeof(char)*11) + sizeof(float) +    
          sizeof(float) + (sizeof(char)*101);

     fread (&super, tamStructSuper, 1, ptrFile );   
.............................
De tanto practicar Tengo una nueva duda, si reemplazo las 5 líneas de fread por la última, debo suponer que siempre el resultado será el correcto ¿estoy en lo cierto?.-
Si me preguntaran a mí diría que sí pero siempre me gusta preguntar a los expertos, por las dudas.-

Daniel
  #6 (permalink)  
Antiguo 10/04/2015, 00:15
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Hola Daniel! Efectivamente así es.

Tenga en cuanta que tanto fread como fwrite escriben/leen n números de veces el tamaño de esos sizeofs.

Si tengo fread ( &super, tamStructsuper, 1, ptrFile ); Estoy leyendo tamStructsuper*1 numero de registros.

Lo mismo ocurre con fwrite ( &super, tamStructsuper, 1, ptrFile ), escribo 1 objeto del tamaño de tamStructsuper.

  #7 (permalink)  
Antiguo 10/04/2015, 03:20
 
Fecha de Ingreso: julio-2012
Mensajes: 133
Antigüedad: 11 años, 9 meses
Puntos: 22
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Hola rdv316.

Solo un detalle, en el segundo bloque de código estas leyendo:
Código C:
Ver original
  1. fread( &super->b, ... // (referencia a "b")
el uso de "->" me indica que "super" se trata de un apuntador a la estructura.

Pero en tu tercer bloque de código, lees de este modo:
Código C:
Ver original
  1. fread( &super, ....
Esa línea te generará un error, por que en este caso estas enviando como argumento la referencia al apuntador no a la estructura.

Al ser "super" un puntero a struct, debería ser:
Código C:
Ver original
  1. fread( super, ...

Saludos.
  #8 (permalink)  
Antiguo 10/04/2015, 05:48
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Bueno, si.. Es tener claro que fread espera un puntero. En fin... No viene al caso aquí el tema de los punteros, si tiene alguna duda sobre eso que se abra otro tema, pero que se este atento a eso.
  #9 (permalink)  
Antiguo 10/04/2015, 07:21
rdv316
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Hola.
Vangodp, en cuanto a lo primero lo tengo claro, con respecto a los punteros y a pesar de que leí muchísimo sobre los mismos debo reconocer que en algunos casos todavía estoy adivinando si asterisco (*) si o asterisco no.-
Ecfisa, fue copiar y pegar y no puse la debida atención, lo copié de códigos distintos.-

Danie
  #10 (permalink)  
Antiguo 10/04/2015, 08:48
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: Mostrar los últimos 5 registros de un archivo [C]

Si.. El tema de punteros es lioso, a mi también me dan dolores de cabeza aun jaja

Etiquetas: char, funcion, int, programa, registros
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 18:31.