[C con Clase] Resumen de Cconclase, Vol 57, Envío 1

Steven Davidson srd4121 en njit.edu
Mar Feb 1 22:37:44 CET 2011


Hola Edinson,

On 2/1/2011 2:21 PM, Edinson Vivas wrote:
> // estructura destinada al registro alumnos
> struct Estudiante
> {
> 	unsigned long int cedula;
> 	char pnombre[50];
> 	char snombre[50];
> 	char papellido[50];
> 	char sapellido[50];
> 	int codsemestre;
> 	int codcarrera;
> 	int matriculadas;
> 	int materia [6];
> 	unsigned long int telefono;

No aconsejo implementar 'telefono' como un valor entero. Sugiero usar 
una cadena de caracteres.

> }lista[100];
>
> Esta es la estructura, si deseo integrar a mi proyecto, una opción
> para eliminar los datos de cualquier alumno, como seria ?
>

Como se trata de un array (de estructuras), no puedes eliminar un 
elemento de un array. Una solución, que podemos hacer, es la que te 
comentaron otros socios: "marca" un elemento (una estructura) como 
"eliminado". Esto significa que cada elemento debe contener un atributo 
dedicado para esta marcación. O bien, tenemos que agregar otro dato 
miembro de esta estructura para tal marcación; por ejemplo,

struct Estudiante
{
   bool bEliminado;
   unsigned long int cedula;
   ...
};

O bien, podemos usar un dato miembro existente el cual puede guardar un 
valor inválido para su propósito, pero podemos interpretarlo como 
"eliminado"; por ejemplo,

struct Estudiante
{
   unsigned long int cedula;
   ...
};

Como 'cedula' debe ser mayor que 0, el valor de 0 es inválido para este 
concepto. Por lo tanto, podemos usar este campo y con un valor de 0 para 
indicar que esta estructura está eliminada. Posiblemente podamos elegir 
otro campo, como por ejemplo, 'pnombre' que no tiene sentido que sea una 
cadena nula: "".

En cualquier caso, tu programa deberá interpretar este dato miembro y su 
valor para poder tratar el array y sus elementos correctamente.


La otra solución con un array es mantener todos los elementos válidos 
agrupados y separados de todos los elementos inválidos porque están 
eliminados. Además, mantenemos una variable para indicar la cantidad 
actual de elementos en el array. Esto supone que cada vez que tengamos 
que eliminar un elemento, debemos recolocar la sublista de elementos 
válidos posteriores a tal elemento a eliminar para mudarlos a la 
"izquierda", para que estén todos los elementos válidos agrupados. Por 
ejemplo,

Si tenemos 40 elementos y queremos eliminar 'lista[5]', entonces tenemos 
que copiar todos los elementos entre 'lista[6]' y 'lista[39]' (ambos 
incluidos) para que empiecen en 'lista[5]' - el elemento a eliminar. 
Obviamente, después de esta copia (o mudanza) restamos uno a la cantidad 
actual de elementos del array.


Otras soluciones existen si no usas un array, sino estructuras 
dinámicas, pero no sé si se te permite o no.

> Yo coloque lo siguiente: lista[contador].cedula = NULL; (buscándolo

No sugiero usar la constante simbólica 'NULL', al menos que la hayas 
definido tú mismo. Elige un valor apropiado y conocido.

> por elemento cedula, mostrando su información y luego corroborando
> si los datos son ciertos me permita modificarlos y/o eliminarlos).
>
> Esto lo hace, pero lo malo, es que si el registro se encuentra
> ubicado en la posicion: por ejemplo lista[10]...
> Se eliminaran todos los registros posteriores a el... osea

Esto no debería ocurrir. Al fin y al cabo, tú eres quién dicta la 
interpretación de esta marcación.

> lista[11]..., lista[12]..., etc... Hasta llenar nuevamente ese
> espacio vacio (NULL), luego de haberlo llenado aparecen los datos
> posteriores como si no fuera pasado nada xD... osea lista[11]...,
> lista[12]..., etc...
>
> Alguna sugerencia ?
>

Como he mencionado, debe ser algún error en tu interpretación de la 
marcación. Sin ver algo de código fuente donde se encuentra este 
comportamiento extraño, no puedo entrar en detalles.


Espero que todo esto te oriente.

Steven





Más información sobre la lista de distribución Cconclase