/* EJEMPLO DE UN PROCESO DE CUNSULTA SENCILLO DE UN FICHERO DIRECTO EN C */ #include #include #include #include #include /* DEFINICIONES Y VARIABLES GLOBALES */ typedef struct { char nombre[30]; int edad; int curso; int notas; } TIPOALUMNO; TIPOALUMNO RALUMNO; /* Registro donde leo o escribo */ FILE * fent; /* Puntero a estructura Fichero */ long pos; /* Posición actual dentro del fichero */ /* ---------------------------------------------------------------*/ /* MUESTRA UNA LINEA DE MENUS CON LAS LETRAS INICIALES ILUMINADAS */ /* ---------------------------------------------------------------*/ void VerMenu ( void ) { textbackground( LIGHTGRAY); clrscr(); textcolor(MAGENTA); gotoxy (10,3); cputs("A R C H I V O D E A L U M N O S"); textcolor(BLUE); gotoxy (5,24); cprintf ("S"); highvideo(); cprintf ("iguiente "); lowvideo(); cprintf ("A"); highvideo(); cprintf ("nterior "); lowvideo(); cprintf ("P"); highvideo(); cprintf ("rimero "); lowvideo(); cprintf ("U"); highvideo(); cprintf ("ltimo "); lowvideo(); cprintf ("O"); highvideo(); cprintf ("tro "); cprintf ("L. "); lowvideo(); cprintf ("T"); highvideo(); cprintf ("otal "); cprintf ("L.Par"); lowvideo(); cprintf ("c"); highvideo(); cprintf ("ial "); lowvideo(); cprintf ("M"); highvideo(); cprintf ("odificar "); lowvideo(); cprintf ("F"); highvideo(); cprintf ("in :"); textcolor(WHITE); } /* ---------------------------------------------------------------*/ /* Pide nuevos valores para rellenar un registro de alumnos */ /* ---------------------------------------------------------------*/ void LeerCampos ( void ) { gotoxy(24,10); cprintf(" "); gotoxy(24,11); cprintf(" "); gotoxy(24,12); cprintf(" "); fflush(stdin); gotoxy(24,10); cgets(RALUMNO.nombre); gotoxy(24,11); cscanf("%d",& RALUMNO.edad); gotoxy(24,12); cscanf("%d",& RALUMNO.curso); } /* ---------------------------------------------------------------*/ /* Muestra por pantalla la información de un registro */ /* ---------------------------------------------------------------*/ void VerCampos ( void ) { gotoxy(15,10); cprintf(" NOMBRE:"); gotoxy(15,11); cprintf(" EDAD :"); gotoxy(15,12); cprintf(" CURSO :"); textcolor(GREEN); gotoxy( 15, 8); cprintf(" N§ Reg :"); textbackground(BLACK); textcolor(BLUE); cprintf("%5d",ftell(fent)/sizeof(RALUMNO)); textcolor(GREEN); gotoxy( 24,10); cprintf("%-15.15s",RALUMNO.nombre); gotoxy( 24,11); cprintf("%3d",RALUMNO.edad); gotoxy( 24,12); cprintf("%3d",RALUMNO.curso); textcolor(WHITE); textbackground(LIGHTGRAY); } /* ---------------------------------------------------------------*/ /* Lee un caracter que este dentro de la cadena de control */ /* ---------------------------------------------------------------*/ char LeerOpcion ( char * pcontrol ) { int numc; char letra; short i; numc = strlen ( pcontrol); while ( 1 ) { gotoxy(78,24); letra = toupper(getch()); for (i=0 ; i < numc ; i++ ) { if ( letra == pcontrol[i] ) { return letra; } } } } /* ---------------------------------------------------------------*/ /* Muestra un Mensaje de error */ /* ---------------------------------------------------------------*/ void VerError ( char *msg ) { textcolor(RED+BLINK); gotoxy(15,20); cputs( msg ); ungetch(getch()); textcolor(WHITE); gotoxy(15,20); cputs(" "); } /* Lee registro siguiente */ void Siguiente ( void ) { if ( fread(&RALUMNO,sizeof(RALUMNO),1,fent) ==0 ) { VerError("Fin de Fichero."); } } /* ---------------------------------------------------------------*/ /* Lee en registro anterior al actual */ /* ---------------------------------------------------------------*/ void Anterior( void ) { long pos; /* Obtengo la posición de un registro anterior */ pos = ftell(fent) - (2L * sizeof(RALUMNO)); /* Si no es antes del principio de fichero */ if ( pos >= 0 ) { fseek(fent,pos,SEEK_SET); fread(&RALUMNO,sizeof(RALUMNO),1,fent); } else { VerError("Inicio del fichero"); } } /* ---------------------------------------------------------------*/ /* Me situo y leo un registro determinado del fichero */ /* ---------------------------------------------------------------*/ void Otro ( void ) { long new_pos; long max_pos; long num_reg; /* Calculo la posición del ultimo registro */ fseek(fent,0L,SEEK_END); max_pos = ftell(fent) - sizeof(RALUMNO); do { do { gotoxy(24, 8); cprintf(" "); gotoxy(15, 8); cprintf(" N§ Reg :"); fflush(stdin); } while ( 1 != scanf("%ld",&num_reg)); /* Posición en Número de registro */ new_pos = ( num_reg - 1) * sizeof(RALUMNO); } while ( ( new_pos < 0 ) || ( new_pos > max_pos ) ); fseek(fent,new_pos,SEEK_SET ); fread(&RALUMNO, sizeof(RALUMNO), 1, fent ); } /* ---------------------------------------------------------------*/ /* Me situo en el primer registro del fichero */ /* ---------------------------------------------------------------*/ void Primero( void ) { fseek(fent,0L,SEEK_SET); fread(&RALUMNO, sizeof(RALUMNO),1, fent); } /* ---------------------------------------------------------------*/ /* Me situo en el ultimo registro del fichero */ /* ---------------------------------------------------------------*/ void Ultimo ( void ) { fseek(fent, 0L - sizeof(RALUMNO),SEEK_END); fread(&RALUMNO, sizeof(RALUMNO), 1, fent); } /* ---------------------------------------------------------------*/ /* Listado Parcial entre posiciones */ /* ---------------------------------------------------------------*/ void Listado_Parcial( void ) { long pos_old; // Posición física actual long pos_ini; // Primera posición física long pos_fin; // Ultima posición física long pos_max; // Posición fisica máxima long numro; // Primer registro long numrf; // Ultimo registro // Pantalla en blanco y negro textbackground(BLACK); clrscr(); // Guardo la posición actual pos_old = ftell(fent); // Obtengo la posición máxima fseek(fent,0L,SEEK_END); pos_max = ftell(fent) - sizeof(RALUMNO); gotoxy(10,10); cprintf(" Posici¢n Inicial :"); gotoxy(10,11); cprintf(" Posici¢n Final :"); do { // Compruebo el scanf do { fflush(stdin); gotoxy(30,10); clreol(); } while (scanf("%ld",&numro) != 1) ; // Compruebo el scanf do { fflush(stdin); gotoxy(30,11); clreol(); } while (scanf("%ld",&numrf) != 1) ; pos_ini = (numro -1) * sizeof(RALUMNO); pos_fin = (numrf -1) * sizeof(RALUMNO); } while ( ( pos_ini > pos_fin ) || ( pos_fin > pos_max ) ); gotoxy(1,5); printf("\t LISTADO PARCIAL DE ALUMNOS \n\n"); printf("\t=================================================\n"); printf("\t N§ NOMBRE EDAD CURSO \n"); printf("\t=================================================\n"); fseek(fent,(long) pos_ini,SEEK_SET); fread(&RALUMNO,sizeof(RALUMNO),1,fent); while ( numro <= numrf ) { printf("\t%3d %-30s %4d %4d \n",numro,RALUMNO.nombre, RALUMNO.edad, RALUMNO.curso); fread(&RALUMNO,sizeof(RALUMNO),1,fent); numro++; } printf("\t=================================================\n"); // Vuelvo a la posición anterior y muestro el menu y el registro fseek(fent,pos_old-sizeof(RALUMNO),SEEK_SET); getch(); Siguiente(); VerMenu(); VerCampos(); } /* ---------------------------------------------------------------*/ /* Listado total de alumnos */ /* ---------------------------------------------------------------*/ void Listado_Total ( void ) { long pos_old; short numr; /* Guardo la posición actual */ pos_old = ftell(fent); // Pantalla en blanco y negro textbackground(BLACK); clrscr(); gotoxy(1,5); printf("\t LISTADO TOTAL DE ALUMNOS \n\n"); printf("\t=================================================\n"); printf("\t N§ NOMBRE EDAD CURSO \n"); printf("\t=================================================\n"); fseek(fent,0L,SEEK_SET); fread(&RALUMNO,sizeof(RALUMNO),1,fent); numr = 1; while ( !feof(fent) ) { printf("\t%3d %-30s %4d %4d \n",numr,RALUMNO.nombre, RALUMNO.edad, RALUMNO.curso); fread(&RALUMNO,sizeof(RALUMNO),1,fent); numr++; } printf("\t=================================================\n"); /* Recupero la posición antigua y vuelvo a pintar el menu y el registro */ fseek(fent,pos_old-sizeof(RALUMNO),SEEK_SET); getch(); Siguiente(); VerMenu(); VerCampos(); } /* ---------------------------------------------------------------*/ /* Modifica el registro actual */ /* ---------------------------------------------------------------*/ void Modificar( void ) { long pos; /* Modifico */ RALUMNO.curso ++; /* Muevo el puntero para atras */ pos = ftell(fent) - sizeof(RALUMNO); // fseek(fent, - sizeof(RALUMNO),SEEK_CUR); fseek(fent,pos,SEEK_SET); /* Escribo */ fwrite(&RALUMNO,sizeof(RALUMNO),1,fent); /* LLamo a fseek para poder seguir leyendo */ /* No se puede hacer fwrite y fread seguidos */ fseek(fent,ftell(fent),SEEK_SET); } /* ---------------------------------------------------------------*/ /* PROGRAMA PRINCIPAL */ /* Abre el fichero, muestra el primer registro y entra el ciclo del menu */ /* ---------------------------------------------------------------*/ void main () { char opcion; fent = fopen("ALUMNOS.DAT","rb+"); if ( fent == NULL ) { perror("fopen"); exit(1); } /* Muestro el menu y el primer registro */ VerMenu(); Siguiente(); VerCampos(); opcion = LeerOpcion("SAOPUMTCF"); while (opcion != 'F') { switch ( opcion ) { case 'S': Siguiente (); break; case 'A': Anterior (); break; case 'O': Otro (); break; case 'P': Primero(); break; case 'U': Ultimo(); break; case 'M': Modificar(); break; case 'T': Listado_Total(); break; case 'C': Listado_Parcial(); } VerCampos(); opcion = LeerOpcion("SAOPUMTCF"); } fclose(fent); exit(0); }