Comprobar si existe registro
Alguien me podria ayudar a saber de que manera puedo saber si un registro ya existe en la lista, esto es lo que tengo:
gets (datos.apodo);
gets (datos.nombre);
...
fwrite (&datos,sixeof(datos),1,F1);
Lo que quiero hacer es que solo valide el campo apodo, si no ya existe mande un mensaje y si no que lo agrege.
Espero que me puedan ayudar.
gets (datos.apodo);
gets (datos.nombre);
...
fwrite (&datos,sixeof(datos),1,F1);
Lo que quiero hacer es que solo valide el campo apodo, si no ya existe mande un mensaje y si no que lo agrege.
Espero que me puedan ayudar.
Quiza deberias mirarte algo sobre hashes quiza te sirva .
Para tu ejemplo lo que tendrias que hacer es leer todos los string nombre metidos y compararlos con tu nuevo dato ,entonces si coincide comparas el apodo ,pero esto es muy lento y poco efectivo.Entonces para solucionarlo se puede recurrir
a los hashes ,te explico brevemente como funciona la cosa ,aunque un poco a mi manera para hacerlo mas sencillo .
Pongamos que tienes
una estructura de este tipo
struct ficha {
char nombre[20];
char apodo[20];
}
Ahora hacemos una lista de 100
struct ficha datos[100];
la escribimos en el fichero
fwrite(datos,sizeof(struct ficha),100,archivo);
Ahora queremos actualizarla ,pero no sabemos si ya existe ese registro ,que podemos hacer?
Pues podemos incluir en cada struct datos que sean unicos segun ese nombre y nos ayuden a comparar de forma rapida ,para ello podemos utilizar datos de tipo long ,entonces la estructura quedaria una cosa asi :
struct ficha {
long IndiceNombre;
char nombre[20];
char apodo[20];
}
Entonces en los indices aplicamos una funcion de forma que genere un valor entero mediante el nombre por ej:
tenemos el nombre "pepe"
le aplicamos una funcion a cada caracter ,por ej;
datos[0].IndiceNombre=0;
srand(2432);
for(i=0;i<strlen(nombre);i++)
datos[0].IndiceNombre+=(nombre[i]*rand());
Entonces que hemos hecho con esto ,pues hemos aplicado una funcion al nombre multiplicando cada caracter por una secuencia de numeros pseudoaleatorios generada por rand() y a partir de una semilla conocida ,lo que implica que siempre que se llame a ese srand(2432) rand() generara la misma secuencia de numeros aleatorios .
Una vez aqui ya hemos generado el indice para este nombre ,de igual modo generariamos el indice para el apodo y para las demas estructuras .
Entonces ahora tienes un nuevo nombre y quieres ver
si existe en la lista ,que hacemos?
Calculamos su IndiceNombre igualmente que antes ,entonces leemos todas las estructuras con un fread y comparamos ese IndiceNombre con los IndiceNombre de las estructuras que tenemos ,es una comparacion de longs (a diferencia de comparar char a char es muchisimo mas rapida) ,si el IndiceNombre coincide en los 2 entonces pasamos a comparar el string (ya que puede haber colisiones y haber generado el mismo indice nombres diferentes)y si coincide ya sabemos que ese pasamos a comparar el apodo con el apodo que habia y si es diferente actualizamos.
es el campo donde
Bueno este es un ejemplo de mas o menos como funciona ,la funcion que he puesto es inventada ahora,quiza sea muy lenta no lo se,pero con hacer una que sea rapida y no genere casi colisiones vale
por ej si haces una que sume todos los caracteres seguramente tendras muchas colisiones ,pero si al primer caracter lo multiplicas por el segundo ,a ese resultado le sumas el tercero y a ese resultado lo multiplicas por el cuarto caracter ,y asi sucesivamente seguro que tiene pocas colisiones y es rapido de ejecutar .
Y esto es todo ,luego tienes las tablas hash que hacen que haya muchisimas menos comparaciones
pero si quieres profundizar mejor busca algo por inet.
Para tu ejemplo lo que tendrias que hacer es leer todos los string nombre metidos y compararlos con tu nuevo dato ,entonces si coincide comparas el apodo ,pero esto es muy lento y poco efectivo.Entonces para solucionarlo se puede recurrir
a los hashes ,te explico brevemente como funciona la cosa ,aunque un poco a mi manera para hacerlo mas sencillo .
Pongamos que tienes
una estructura de este tipo
struct ficha {
char nombre[20];
char apodo[20];
}
Ahora hacemos una lista de 100
struct ficha datos[100];
la escribimos en el fichero
fwrite(datos,sizeof(struct ficha),100,archivo);
Ahora queremos actualizarla ,pero no sabemos si ya existe ese registro ,que podemos hacer?
Pues podemos incluir en cada struct datos que sean unicos segun ese nombre y nos ayuden a comparar de forma rapida ,para ello podemos utilizar datos de tipo long ,entonces la estructura quedaria una cosa asi :
struct ficha {
long IndiceNombre;
char nombre[20];
char apodo[20];
}
Entonces en los indices aplicamos una funcion de forma que genere un valor entero mediante el nombre por ej:
tenemos el nombre "pepe"
le aplicamos una funcion a cada caracter ,por ej;
datos[0].IndiceNombre=0;
srand(2432);
for(i=0;i<strlen(nombre);i++)
datos[0].IndiceNombre+=(nombre[i]*rand());
Entonces que hemos hecho con esto ,pues hemos aplicado una funcion al nombre multiplicando cada caracter por una secuencia de numeros pseudoaleatorios generada por rand() y a partir de una semilla conocida ,lo que implica que siempre que se llame a ese srand(2432) rand() generara la misma secuencia de numeros aleatorios .
Una vez aqui ya hemos generado el indice para este nombre ,de igual modo generariamos el indice para el apodo y para las demas estructuras .
Entonces ahora tienes un nuevo nombre y quieres ver
si existe en la lista ,que hacemos?
Calculamos su IndiceNombre igualmente que antes ,entonces leemos todas las estructuras con un fread y comparamos ese IndiceNombre con los IndiceNombre de las estructuras que tenemos ,es una comparacion de longs (a diferencia de comparar char a char es muchisimo mas rapida) ,si el IndiceNombre coincide en los 2 entonces pasamos a comparar el string (ya que puede haber colisiones y haber generado el mismo indice nombres diferentes)y si coincide ya sabemos que ese pasamos a comparar el apodo con el apodo que habia y si es diferente actualizamos.
es el campo donde
Bueno este es un ejemplo de mas o menos como funciona ,la funcion que he puesto es inventada ahora,quiza sea muy lenta no lo se,pero con hacer una que sea rapida y no genere casi colisiones vale
por ej si haces una que sume todos los caracteres seguramente tendras muchas colisiones ,pero si al primer caracter lo multiplicas por el segundo ,a ese resultado le sumas el tercero y a ese resultado lo multiplicas por el cuarto caracter ,y asi sucesivamente seguro que tiene pocas colisiones y es rapido de ejecutar .
Y esto es todo ,luego tienes las tablas hash que hacen que haya muchisimas menos comparaciones
pero si quieres profundizar mejor busca algo por inet.
