borrado lógico y físico de registros en un archivo

Luis
25 de Octubre del 2004
hola, soy nuevo en este foro y espero que alguien me pueda ayudar a hacer una función de borrado lógico y físico de un registro en un archivo, el borrado lógico ya lo tengo más o menos hecho y consiste en agregarle al principio del registro borrado un * pero el físico no me queda y consiste en de acuerdo a los registros que se hayan borrado lógicamente pasar solo los registros no borrados a un archivo nuevo y luego eliminar el archivo viejo y renombrar el nuevo, si alguien fuera tan amable de ayudarme con este problema le agradecería bastante les pongo acá el código:

#include <C:Luisarches.h>
#include <C:Luistomarc.c>
#include <C:Luishazllave.c>
#define LONG_REG 64
#define campo_a_buffreg(br,cad) strcat(br,cad); strcat(br,DELIM_CAD);

int men=0;
static char *solicitud[] = { " Apellido: ",
" Nombre: ",
" Direcci¢n: ",
" Ciudad: ",
" Estado: ",
" Cod. Post: ",
"" };

static int fd,fdb;

static struct {
short cont_reg;
char relleno[30];
} encabezado,encabezado1;

void main() {

int i,menu_elec,nrr,flag;
int byte_pos,a,aux=0;
char fn[15], temp[20];
char ext[]="bak";
char buffreg[TAM_MAX_REG+1]; /*buffer para guardar un registro */
textcolor(58);
clrscr();
printf("Proporcione el nombre del archivo: ");
gets(fn);
if((fd=open(fn,LECTESCRIT))<0) /*Si falla OPEN*/
{
fd=creat(fn,PMODE); /*Entonces CREAT*/
encabezado.cont_reg=0; /*Inicia encabezado*/
write(fd,&encabezado,sizeof(encabezado)); /*Escribe el reg. de encabezado*/
}
else /*Se abre el archivo existente - se lee el encabezado*/
read(fd,&encabezado,sizeof(encabezado));

/*Ciclo del programa principal - llama al menú y después salta a las opciones*/

while((menu_elec = menu()) < 5)
{
switch(menu_elec)
{
case 1: /*Agrega un registro nuevo*/
printf("Proporcione la informaci¢n del registro nuevo:nn");
pide_info(buffreg);
byte_pos=encabezado.cont_reg * LONG_REG + sizeof(encabezado);
lseek(fd,(long) byte_pos, 0);
write(fd,buffreg,LONG_REG);
encabezado.cont_reg++;
break;
case 2: a=0; /*Actualiza un registro existente*/
nrr=pide_nrr(a);
/*Si el NRR es muy grande, imprime mensaje de error... */
if(nrr >= encabezado.cont_reg)
{
printf("El n£mero de registro es demasiado grande...");
printf("..... se vuelve al men£ .....");
break;
}
/*En caso contrario, se coloca en el registro... */

byte_pos=nrr*LONG_REG+sizeof(encabezado);
lseek(fd, (long) byte_pos,0);

/*Lo despliega y pide los cambios*/
flag=lee_y_muestra();
if(flag==0){
if(cambio())
{
printf("nnProporciona los valores revisados: nn");
pide_info(buffreg);
lseek(fd,(long) byte_pos,0);
write(fd,buffreg,LONG_REG);
}
}
break;

case 3: a=1; /*Hace un borrado l¢gico*/
nrr=pide_nrr(a);
/*Si el NRR es muy grande, imprime mensaje de error... */
if(nrr >= encabezado.cont_reg)
{
printf("El n£mero de registro es demasiado grande...");
printf("..... se vuelve al men£ .....");
break;
}
/*En caso contrario, se coloca en el registro... */

byte_pos=nrr*LONG_REG+sizeof(encabezado);
lseek(fd, (long) byte_pos,0);

/*Lo despliega y pregunta si ser  borrado*/
flag=lee_y_muestra();
if(flag==0){
if(logdel())
{
lseek(fd,(long) byte_pos,0);
write((fd),("*"),1);
write((fd),(buffreg),strlen(buffreg));
}
}
break;
}
}

/*Reescribe la suma de registros correcta en el encabezado antes de terminar.*/

lseek(fd,0L,0);
write(fd, &encabezado, sizeof(encabezado));
close(fd);
}


/* menu()...
Función local que pide al usuario la siguiente operación.
Devuelve el valor numérico de la respuesta del usuario.
*/

static menu() {
int eleccion;
char resp[10];
printf("nnnn PROGRAMA DE ACTUALIZACION DEL ARCHIVO n");
printf("nnUsted Puede elegir: nn");
printf("n1. Agregar un registro al final del archivon");
printf("n2. Extraer un registro para actualizarlon");
printf("n3. Borrado l¢gicon");
printf("n4. Borrado f¡sicon");
printf("n5. Salir del programa nn");
printf("Proporcione el n£mero de su elecci¢n: ");
gets(resp);
eleccion=atoi(resp);
return (eleccion);
}


/*pide_info[]...
Función local que lee los campos de nombre y dirección
transcribiendolosal buffer que se pasa como parámetro
*/


static pide_info(char buffreg[])
{
int cont_campos, i;
char resp[50];
/*Limpia el buffer del registro */
for(i=0; i< LONG_REG; buffreg[i++]='')
;
/*toma los campos*/
for(i=0; *solicitud[i] != ''; i++)
{
printf("%s",solicitud[i]);
gets(resp);
campo_a_buffreg(buffreg,resp);
}
}


/*pide_nrr()...

Funci¢n local que pide el n£mero relativo del registro
que se actualizar  o borrar  para lo cu l se le pasa un parametro.

*/

static pide_nrr(int a)
{

int nrr;
char resp[10];

printf("nnDigite el n£mero relativo del registron");
/*Aqu¡ se determina de cu l funci¢n viene si es extraer registro*/
if(a==0)
printf("tque desee actualizar: ");
/*Aqu¡ se determina si viene de la funci¢n borrar registro*/
if(a==1)
printf("tque desee borrar: ");
gets(resp);
nrr=atoi(resp);
return(nrr);
}


/* lee_y_muestra()...

Función local que lee y despliega un registro. Nótese que esta
función no incluye localización: la lectura empieza en la
posición actual del archivo.

*/

static lee_y_muestra()
{

char buffreg[TAM_MAX_REG+1], campo[TAM_MAX_REG+1];
int pos_bus, long_datos,i=0;
int band=0;

pos_bus=0;
read(fd,buffreg,LONG_REG);
printf("nContenido del registro existente:n");
buffreg[LONG_REG]=''; /*Se asegura que el registro termine con nulo*/
long_datos=strlen(buffreg);
while((pos_bus=toma_campo(campo,buffreg,pos_bus,long_datos))>0&&band<1){
if(campo[0]=='*'){
printf("El Archivo que usted Busca fue borrado logicamente...");
band=1;
getch();
}
else printf("t%st%sn",solicitud[i++],campo);
}
return(band);
}

/* cambio()...

Función local que pregunta al usuario si quiere cambiar el registro.
Devuelve 1 si la respuesta es s¡ y 0 en caso contrario.

*/

static cambio()
{

char resp[10];

printf("nn¨Desea modificar este registro?n");
printf(" Conteste S o N, seguido por <ENTER>: ");
gets(resp);
mayusculas(resp,resp);
return((resp[0]=='S') ? 1 : 0 );
}

/* logdel()...

Funci¢n de borrado l¢gico logdel que pregunta si en realidad
se quiere borrar el registro que se mostro en pantalla

*/

static logdel()
{

char resp[10];

printf("nn¨Desea borrar logicamente este registro?n");
printf(" Conteste S o N, seguido por <ENTER>: ");
gets(resp);
mayusculas(resp,resp);
return((resp[0]=='S') ? 1 : 0 );
}